diff options
author | Alexander Kriegisch <Alexander@Kriegisch.name> | 2024-01-30 10:00:56 +0700 |
---|---|---|
committer | Alexander Kriegisch <Alexander@Kriegisch.name> | 2024-01-30 12:39:24 +0700 |
commit | 5665de78868050d9964a315fb5e3628bd6696c62 (patch) | |
tree | 08449691b6329e02c2e86def4246f31bb4cb3823 /docs/modules/ROOT/pages/teaching/exercises | |
parent | e91e8f96fd620672d2fdf182a0a8708116d3464b (diff) | |
download | aspectj-5665de78868050d9964a315fb5e3628bd6696c62.tar.gz aspectj-5665de78868050d9964a315fb5e3628bd6696c62.zip |
Change directory layout to suit Antora
Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'docs/modules/ROOT/pages/teaching/exercises')
74 files changed, 3740 insertions, 0 deletions
diff --git a/docs/modules/ROOT/pages/teaching/exercises/README.txt b/docs/modules/ROOT/pages/teaching/exercises/README.txt new file mode 100644 index 000000000..91c8c3e52 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/README.txt @@ -0,0 +1,124 @@ +AspectJ Figures Exercises +------------------------------ + +This file is really out-of-date. We're in the middle of recovery +from OOPSLA 2004, and we need to move stuff around in this +package. In particular, we need to build in a new structure. + +One idea is that we should have _four_ projects within the +workspace, one for each problem set. There's still a bit of work +necessary to avoid duplicating code here (in CVS) even though we +want to duplicate code in the generated workspaces. + +------------------------------ +Generated Structure + +We want a particular _generated_ structure for users. We're +eventually going to dump to a zip file or a CD. + +Folder: aj-<event>: + /eclipse (arch) + /workspace (noarch) + /packages (noarch) + j2sdk for win, linux + aspectj for everybody + +------------------------------ +Requirements for users: + +* We learned at OOPSLA 2004 that the system doesn't work well at + all under linux using the blackdown JDK. Use Sun's jdk! + + +------------------------------ +------------------------------ + +THIS FILE IS OUT-OF-DATE !!! (2003-3-17) + +These exercises are designed to be used with AspectJ 1.0.6. + +THEY MUST NOT BE DISTRIBUTED ELECTRONICALLY WITHOUT THINKING FIRST!!! +There may be licence issues with just sticking the junit jar in there +that I don't understand. + +To build distribution zips, use ant -f build.xml. This will create + + EV-exercises.zip -- the contents of these exercises, minus AspectJ + EV-answers.zip -- some answers to these exercises. + EV-setup.zip -- the exercises bundled with AspectJ + EV-allcontent.zip -- the exercises bundled with the answers + + +If you don't want to be bothered with specifying where AspectJ is, +feel free to just do ant -f build.xml answers.zip. By default it will +build both exercises and answers. + +------------------------------ +Required environment + +In order to actually do the exercises, the three very important files +to have are: + + EV-exercises.zip + aspectj-tools-1.0.6.jar + <some installer of java> + +It is almost certainly a good idea to hope that Java is already +installed on the students' systems, but to provide two installers +(windows and linux) anyway. + + http://java.sun.com + +You may want to also include the rest of the AspectJ installers as +well, but that might be a bit of a distraction + + http://aspectj.org/dl + +These require junit.jar. I've included a copy in with the two zip +files, but they might want to be refreshed every now and again. + + http://junit.org + + +------------------------------ +Printing + +It would be really nice to have an automated solution to generate the +documents, but no such luck. + +* index.html should print out with useful page breaks. It should be + separated into four chunks if possible. + +* answers in four chunks. + +* quick reference sheets. + +Remember to have a one-sided copy of everything as a separate +clean-copy. + + +------------------------------ +Distribution + + /j2sdk-1_4_1_01-linux-i586.bin + /j2sdk-1_4_1_01-windows-i586.exe + /exercises.zip containing: + aj-EV/src/figures.zip + aj-EV/src/aspectj-tools-1.0.6.jar + aj-EV/src/aspectj-docs-1.0.6.jar + aj-EV/<exploded version of figures.zip> + aj-EV/aspectj/<exploded version of aspectj-tools> + aj-EV/aspectj/<exploded version of aspectj-docs> + aj-EV/setpaths + aj-EV/setpaths.bat + +/bin/ajc, are edited to make sure that JAVA_HOME is used, as the +defaults will almost certainly be wrong. setpaths scripts do what +they look like they do. All six of these scripts are stored in +scripts under CVS. + +---- Instructors + +Since the only difference is the answers, just overwrite the +extraction directory with answers.zip. + diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer.java new file mode 100644 index 000000000..d2030d398 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer.java @@ -0,0 +1,7 @@ +package answers; + +import figures.*; + +aspect Answer { + +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer1a.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer1a.java new file mode 100644 index 000000000..09c41a28d --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +aspect Answer1a { + declare error + : get(java.io.PrintStream System.out) + && within(figures..*) + : "illegal access to System.out"; +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer1b.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer1b.java new file mode 100644 index 000000000..95c6e130d --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +aspect Answer1b { + declare warning + : set(private * *) + && !withincode(* set*(..)) + && within(figures.*) + : "bad field set"; +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer1c.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer1c.java new file mode 100644 index 000000000..f90dc8bcc --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +aspect Answer1c { + declare error + : set(private * *) + && !(withincode(* set*(..)) || withincode(new(..))) + && within(figures.*) + : "bad field set"; +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2a.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2a.java new file mode 100644 index 000000000..46519a83e --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2a.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.Point; +import figures.FigureElement; + +public aspect Answer2a { + before(int newValue): set(int Point.*) && args(newValue) { + if (newValue < 0) { + throw new IllegalArgumentException("too small"); + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2b.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2b.java new file mode 100644 index 000000000..c9ba82bee --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.Group; +import figures.FigureElement; + +public aspect Answer2b { + before(FigureElement newValue): + call(void Group.add(FigureElement)) + && args(newValue) { + if (newValue == null) { + throw new IllegalArgumentException("null not allowed"); + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2c.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2c.java new file mode 100644 index 000000000..2364aaeb0 --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.Group; +import figures.FigureElement; + +public aspect Answer2c { + before(FigureElement newValue, Group g): + call(void Group.add(FigureElement)) + && args(newValue) + && target(g) { + if (newValue == null) { + throw new IllegalArgumentException("null not allowed"); + } + if (newValue == g) { + throw new IllegalArgumentException("self not allowed"); + } + + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2d.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2d.java new file mode 100644 index 000000000..0d99f537f --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +aspect Answer2d { + void around(int val): (set(int Point._x) || set(int Point._y)) + && args(val) { + if (val < 0) + val = 0; + proceed(val); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2e.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2e.java new file mode 100644 index 000000000..7da69c313 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2e.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +import java.awt.Rectangle; + +aspect Answer2e { + void around(Point p, int dx, int dy): + target(p) && call(void move(int, int)) && args(dx, dy) { + int preX = p.getX(); + int preY = p.getY(); + + proceed(p, dx, dy); + + int postX = p.getX(); + int postY = p.getY(); + + if ((postX != preX + dx) || (postY != preY + dy)) { + throw new IllegalStateException("point didn't move properly"); + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2f.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2f.java new file mode 100644 index 000000000..f8992ccf9 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer2f.java @@ -0,0 +1,32 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.*; + +import java.awt.Rectangle; + +aspect Answer2f { + void around(FigureElement fe, int dx, int dy): + target(fe) && call(void move(int, int)) && args(dx, dy) { + + Rectangle preBounds = new Rectangle(fe.getBounds()); + proceed(fe, dx, dy); + + preBounds.translate(dx, dy); + + if (!preBounds.equals(fe.getBounds())) { + throw new IllegalStateException("bounds don't match move"); + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3a.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3a.java new file mode 100644 index 000000000..d48924ee8 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3a.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +aspect Answer3a { + before(): execution(public * *(..)) && within(figures.*) { + Log.write(thisJoinPoint); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3b.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3b.java new file mode 100644 index 000000000..4fe3072fa --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3b.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +import figures.Point; +import figures.Group; +import figures.FigureElement; + +aspect Answer3b { + before(Object o): + execution(public * *(..)) + && !execution(public String toString(..)) + // or perhaps !cflow(adviceexecution()) + && within(figures.*) + && target(o) + { + Log.write(thisJoinPoint + " at " + o); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3c.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3c.java new file mode 100644 index 000000000..198558d06 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3c.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +import figures.*; + +aspect Answer3c { + before(): + execution(void Group.add(FigureElement)) + && args(Point) { + Log.write("adding Point"); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3d.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3d.java new file mode 100644 index 000000000..b2e74218c --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3d.java @@ -0,0 +1,32 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +import figures.*; + +aspect Answer3d { + + private boolean Point.inGroup = false; + + before(Point p): + execution(void Group.add(FigureElement)) + && args(p) { + if (p.inGroup) { + throw new IllegalStateException(); + } else { + p.inGroup = true; + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3e.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3e.java new file mode 100644 index 000000000..505aa22c6 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer3e.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import support.Log; + +import figures.*; + +aspect Answer3e { + + private Group Point.containingGroup = null; + + before(Group g, Point p): + execution(void Group.add(FigureElement)) + && this(g) + && args(p) { + if (p.containingGroup != null) { + throw new IllegalStateException(p.containingGroup.toString()); + } else { + p.containingGroup = g; + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4a.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4a.java new file mode 100644 index 000000000..99fa96cc1 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4a.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import java.awt.Rectangle; + +aspect Answer4a { + Rectangle around(): execution(Rectangle Group.getBounds()) { + return FigureElement.MAX_BOUNDS; + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4b.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4b.java new file mode 100644 index 000000000..2e77fd862 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4b.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import java.awt.Rectangle; + +aspect Answer4b { + private Rectangle Group.cache = null; + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) + && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4c.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4c.java new file mode 100644 index 000000000..c9d0e8415 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4c.java @@ -0,0 +1,36 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import java.awt.Rectangle; + +aspect Answer4c { + private Rectangle Group.cache = null; + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) + && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } + + before(Group g): + call(void move(int, int)) + && target(g) { + g.cache = null; + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4d.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4d.java new file mode 100644 index 000000000..2f019c249 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4d.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import figures.Point; +import java.awt.Rectangle; + +aspect Answer4d { + private Rectangle Group.cache = null; + private Group Point.enclosingGroup = null; + + before(Point p, Group g): + execution(void add(FigureElement)) + && args(p) + && target(g) { + p.enclosingGroup = g; + } + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) + && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } + + before(Point p): + set(* Point.*) + && target(p) { + if (p.enclosingGroup != null) { + p.enclosingGroup.cache = null; + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4e.java b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4e.java new file mode 100644 index 000000000..e3d6fa3d4 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/answers/Answer4e.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package answers; + +import figures.FigureElement; +import figures.Group; +import figures.Point; +import java.awt.Rectangle; + +aspect Answer4e { + private Rectangle Group.cache = null; + private Group FigureElement.enclosingGroup = null; + + before(FigureElement p, Group g): + execution(void add(FigureElement)) + && args(p) + && target(g) { + p.enclosingGroup = g; + } + + Rectangle around(Group g): + execution(Rectangle Group.getBounds()) + && this(g) { + if (g.cache == null) { + g.cache = proceed(g); + } + return g.cache; + } + + before(Point p): + set(* Point.*) + && target(p) { + FigureElement fe = p; + while (fe.enclosingGroup != null) { + fe.enclosingGroup.cache = null; + fe = fe.enclosingGroup; + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/base.lst b/docs/modules/ROOT/pages/teaching/exercises/base.lst new file mode 100644 index 000000000..cb6914637 --- /dev/null +++ b/docs/modules/ROOT/pages/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/Test3a.java +tests/Test3b.java +tests/Test3c.java +tests/Test3d.java +tests/Test3e.java +tests/Test4a.java +tests/Test4b.java +tests/Test4c.java +tests/Test4d.java +tests/Test4e.java diff --git a/docs/modules/ROOT/pages/teaching/exercises/build.xml b/docs/modules/ROOT/pages/teaching/exercises/build.xml new file mode 100644 index 000000000..d35fd5e2a --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/build.xml @@ -0,0 +1,120 @@ +<!-- + +This build script will create a directory called burn that is +_almost_ suitable for burning onto a CD. However, there +are a number of things that should be done to this directory +before actually burning: + +The PDFs in the print directory need to be manually generated. +Use the content of foo.pdf.contents to generate foo.pdf, and +and then delete the foo.pdf.contents directory. + +The powerpoint and packages directory should be populated +with whatever you want to populate it with. The +packages directory is typically filled with Linux installers +and a clean AspectJ installer. +--> + +<project name="build" default="burn" basedir="."> + <description> + Build a CD image containing AspectJ exercises. + </description> + + <!-- CUSTOMIZE THESE PROPERTIES --> + + <!-- this directory should hold a clean unpacked AspectJ release --> + <property name="aj.home" value="c:/apps/aspectj" /> + + <!-- this is the name of the event --> + <property name="aj.event" value="oopsla2004" /> + + <!-- NO CUSTOMIZABLE PROPERTIES BELOW HERE --> + + <property name="burndir" value="burn" /> + <property name="eventdir" value="${burndir}/aj-${aj.event}" /> + <property name="packagedir" value="${burndir}/packages" /> + <property name="printdir" value="${burndir}/print" /> + <property name="powerpointdir" value="${burndir}/powerpoint" /> + + <!-- now real targets --> + <target name="burn" depends="clean,skeleton,event,answers,printables" /> + + <target name="printables" depends="skeleton"> + <delete dir="${printdir}/answers.pdf.contents" /> + <mkdir dir="${printdir}/answers.pdf.contents" /> + <copy toDir="${printdir}/answers.pdf.contents"> + <fileset dir="answers" includes="*.java" excludes="Answer.java"/> + </copy> + + <delete dir="${printdir}/exercises.pdf.contents" /> + <mkdir dir="${printdir}/exercises.pdf.contents" /> + <copy toDir="${printdir}/exercises.pdf.contents" file="index.html" /> + <copy toDir="${printdir}/exercises.pdf.contents" file="figures_classes.pdf" /> + <copy toDir="${printdir}/exercises.pdf.contents" file="${aj.home}/doc/quick.pdf" /> + + <delete dir="${printdir}/install.pdf.contents" /> + <mkdir dir="${printdir}/install.pdf.contents" /> + <copy toDir="${printdir}/install.pdf.contents" file="install.txt" /> + </target> + + <target name="answers" depends="skeleton"> + <zip destfile="${packagedir}/${aj.event}-answers.zip"> + <zipfileset dir="answers" + prefix="aj-${aj.event}/answers" + includes="*.java" + excludes="Answer.java" + /> + </zip> + </target> + + <target name="event" depends="tools,exercises"> + <filter token="aj.event" value="${aj.event}" /> + <copy file="install.txt" toDir="${eventdir}" filtering="yes" /> + </target> + + <target name="exercises" depends="skeleton"> + <copy toDir="${eventdir}"> + <fileset dir="." + includes="junit.jar,base.lst,guibase.lst,*.html,support/**/*.java,figures/**/*.java,tests/**/*.java,answers/Answer.java" + /> + </copy> + </target> + + <target name="tools" depends="skeleton"> + <mkdir dir="${eventdir}/aspectj" /> + <filter token="aj.event" value="${aj.event}" /> + + <copy toDir="${eventdir}/aspectj"> + <fileset dir="${aj.home}" excludes="bin/**" /> + </copy> + <copy toDir="${eventdir}/aspectj/bin" filtering="yes"> + <fileset dir="scripts" excludes="setpaths*" /> + </copy> + <copy toDir="${eventdir}" filtering="yes"> + <fileset dir="scripts" includes="setpaths*" /> + </copy> + <fixcrlf srcDir="${eventdir}" + includes="setpaths.bat,aspectj/bin/ajbrowser.bat,aspectj/bin/ajc.bat" + eol="crlf" /> + <fixcrlf srcDir="${eventdir}" + includes="setpaths.sh,setpaths.csh,aspectj/bin/ajbrowser,aspectj/bin/ajc" + eol="lf" /> + </target> + + <target name="skeleton"> + <mkdir dir="${burndir}" /> + <mkdir dir="${eventdir}" /> + <mkdir dir="${packagedir}" /> + <mkdir dir="${printdir}" /> + <mkdir dir="${powerpointdir}" /> + </target> + + <target name="clean"> + <delete dir="burn" /> + </target> + + <target name="javaclean"> + <delete dir="burn" /> + </target> + +</project> diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures.zargo b/docs/modules/ROOT/pages/teaching/exercises/figures.zargo Binary files differnew file mode 100644 index 000000000..c042c5969 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/figures.zargo diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/Box.java b/docs/modules/ROOT/pages/teaching/exercises/figures/Box.java new file mode 100644 index 000000000..2db991a21 --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Box extends ShapeFigureElement { + private Point _p0; + private Point _p1; + private Point _p2; + private Point _p3; + + public Box(int x0, int y0, int width, int height) { + _p0 = new Point(x0, y0); + _p1 = new Point(x0+width, y0); + _p2 = new Point(x0+width, y0+height); + _p3 = new Point(x0, y0+height); + } + + public Point getP0() { return _p0; } + public Point getP1() { return _p1; } + public Point getP2() { return _p2; } + public Point getP3() { return _p3; } + + public void move(int dx, int dy) { + _p0.move(dx, dy); + _p1.move(dx, dy); + _p2.move(dx, dy); + _p3.move(dx, dy); + } + + public void checkBoxness() { + if ((_p0.getX() == _p3.getX()) && + (_p1.getX() == _p2.getX()) && + (_p0.getY() == _p1.getY()) && + (_p2.getY() == _p3.getY())) + return; + throw new IllegalStateException("This is not a square."); + } + + public String toString() { + return "Box(" + _p0 + ", " + _p1 + ", " + _p2 + ", " + _p3 + ")"; + } + + public Shape getShape() { + return new Rectangle(getP1().getX(), + getP1().getY(), + getP3().getX() - getP1().getX(), + getP3().getY() - getP1().getY()); + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/FigureElement.java b/docs/modules/ROOT/pages/teaching/exercises/figures/FigureElement.java new file mode 100644 index 000000000..ac588f94d --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public interface FigureElement { + public static final Rectangle MAX_BOUNDS = + new Rectangle(0, 0, 500, 500); + + public abstract void move(int dx, int dy); + + public abstract Rectangle getBounds(); + + public abstract boolean contains(Point2D p); + + public abstract void paint(Graphics2D g2); +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/Group.java b/docs/modules/ROOT/pages/teaching/exercises/figures/Group.java new file mode 100644 index 000000000..f8ec65556 --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.util.*; +import java.awt.*; +import java.awt.geom.*; + +public class Group implements FigureElement { + private Collection _members; + private String _identifier; + + public Group(FigureElement first) { + this._members = new ArrayList(); + add(first); + } + + public void add(FigureElement fe) { + _members.add(fe); + } + + public Iterator members() { + return _members.iterator(); + } + + public void move(int dx, int dy) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.move(dx, dy); + } + } + + public void setIdentifier(String identifier) { + _identifier = identifier; + } + + public String toString() { + if (_identifier != null) { + return _identifier; + } + + StringBuffer buf = new StringBuffer("Group("); + for (Iterator i = _members.iterator(); i.hasNext(); ) { + buf.append(i.next().toString()); + if (i.hasNext()) { + buf.append(", "); + } + } + buf.append(")"); + return buf.toString(); + } + + public Rectangle getBounds() { + Rectangle previous = null; + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + Rectangle rect = fe.getBounds(); + if (previous != null) { + previous = previous.union(rect); + } else { + previous = rect; + } + } + return previous; + } + + public boolean contains(Point2D p) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return true; + } + return false; + } + + public void paint(Graphics2D g2) { + for (Iterator i = _members.iterator(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + fe.paint(g2); + } + } + + public int size() { + return _members.size(); + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/Line.java b/docs/modules/ROOT/pages/teaching/exercises/figures/Line.java new file mode 100644 index 000000000..fb3b86b65 --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Line extends ShapeFigureElement { + private Point _p1; + private Point _p2; + + public Line(Point p1, Point p2) { + _p1 = p1; + _p2 = p2; + } + + public Point getP1() { return _p1; } + public Point getP2() { return _p2; } + + public void move(int dx, int dy) { + _p1.move(dx, dy); + _p2.move(dx, dy); + } + + public String toString() { + return "Line(" + _p1 + ", " + _p2 + ")"; + } + + /** + * Used to determine if this line {@link contains(Point2D)} a point. + */ + final static int THRESHHOLD = 5; + + /** + * Returns <code>true</code> if the point segment distance is less than + * {@link THRESHHOLD}. + */ + public boolean contains(Point2D p) { + return getLine2D().ptLineDist(p) < THRESHHOLD; + } + + private Line2D getLine2D() { + return new Line2D.Float((float)getP1().getX(), + (float)getP1().getY(), + (float)getP2().getX(), + (float)getP2().getY()); + } + + public Shape getShape() { + return getLine2D(); + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/Point.java b/docs/modules/ROOT/pages/teaching/exercises/figures/Point.java new file mode 100644 index 000000000..95bd63994 --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public class Point extends ShapeFigureElement { + private int _x; + private int _y; + + public Point(int x, int y) { + _x = x; + _y = y; + } + + public int getX() { return _x; } + + public int getY() { return _y; } + + public void setX(int x) { _x = x; } + + public void setY(int y) { _y = y; } + + public void move(int dx, int dy) { + _x += dx; + _y += dy; + } + + public String toString() { + return "Point(" + _x + ", " + _y + ")"; + } + + /** The height of displayed {@link Point}s. */ + private final static int HEIGHT = 10; + + /** The width of displayed {@link Point}s. -- same as {@link HEIGHT}. */ + private final static int WIDTH = Point.HEIGHT; + + public Shape getShape() { + return new Ellipse2D.Float((float)getX()-Point.WIDTH/2, + (float)getY()-Point.HEIGHT/2, + (float)Point.HEIGHT, + (float)Point.WIDTH); + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/ShapeFigureElement.java b/docs/modules/ROOT/pages/teaching/exercises/figures/ShapeFigureElement.java new file mode 100644 index 000000000..8e7bd34c2 --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +public abstract class ShapeFigureElement implements FigureElement { + public abstract void move(int dx, int dy); + + public abstract Shape getShape(); + + public Rectangle getBounds() { + return getShape().getBounds(); + } + + public boolean contains(Point2D p) { + return getShape().contains(p); + } + + public Color getLineColor() { + return Color.black; + } + + public Color getFillColor() { + return Color.red; + } + + public final void paint(Graphics2D g2) { + Shape shape = getShape(); + g2.setPaint(getFillColor()); + g2.fill(shape); + g2.setPaint(getLineColor()); + g2.draw(shape); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/SlothfulPoint.java b/docs/modules/ROOT/pages/teaching/exercises/figures/SlothfulPoint.java new file mode 100644 index 000000000..89f80d700 --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures; + +import java.awt.*; +import java.awt.geom.*; + +/** + * This class makes mistakes to be caught by invariant checkers. + */ +public class SlothfulPoint extends ShapeFigureElement { + private int _x; + private int _y; + + public SlothfulPoint(int x, int y) { + } + + public int getX() { return _x; } + + public int getY() { return _y; } + + public void setX(int x) { } + + public void setY(int y) { } + + public void move(int dx, int dy) { + System.out.println("Slothful moving"); + } + + public String toString() { + return "SlothfulPoint"; + } + + public Shape getShape() { + return new Ellipse2D.Float((float)_x, + (float)_y, 1.0f, 1.0f); + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/gui/FigurePanel.java b/docs/modules/ROOT/pages/teaching/exercises/figures/gui/FigurePanel.java new file mode 100644 index 000000000..6b264f42a --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures.gui; + +import figures.Point; +import figures.Line; +import figures.FigureElement; +import figures.Group; + + +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.border.*; + +public class FigurePanel extends JComponent { + + ButtonsPanel bp = new ButtonsPanel(); + FigureSurface fs = new FigureSurface(); + ConsolePanel cp = new ConsolePanel(); + + + public FigurePanel() { + setLayout(new BorderLayout()); + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.add(fs); + panel.add(bp); + JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel, cp); + sp.setPreferredSize(new Dimension(500, 400)); + sp.setDividerLocation(250); + add(BorderLayout.CENTER, sp); + } + + class ButtonsPanel extends JPanel { + JLabel msgs = new JLabel("click to add a point or line"); + public ButtonsPanel() { + setLayout(new FlowLayout(FlowLayout.LEFT)); + add(new JButton(new AbstractAction("Main") { + public void actionPerformed(ActionEvent e) { + Main.main(new String[]{}); + fs.repaint(); + } + })); + add(msgs); + } + + public void log(String msg) { + msgs.setText(msg); + } + } + + static class ConsolePanel extends JPanel { + + JTextArea text = new JTextArea(); + + public ConsolePanel() { + super(new BorderLayout()); + text.setFont(StyleContext.getDefaultStyleContext().getFont("SansSerif", Font.PLAIN, 10)); + JScrollPane scroller = new JScrollPane(text); + scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + add(BorderLayout.CENTER, scroller); + } + + public void println(String msg) { + text.append(msg + '\n'); + } + } + + final static Color BACKGROUND = Color.white; + + static class FigureSurface extends JPanel implements MouseListener, MouseMotionListener { + Group canvas; + + public FigureSurface() { + canvas = new Group(new Point(250, 250)); + addMouseMotionListener(this); + addMouseListener(this); + setPreferredSize(new Dimension(500,500)); + } + + private Point addPoint(int x, int y) { + Point p = new Point(x, y); + canvas.add(p); + repaint(); + return p; + } + + private Line addLine(Point p1, Point p2) { + if (Math.abs(p1.getX()-p2.getX()) < 5 || + Math.abs(p1.getY()-p2.getY()) < 5) { + return null; + } + + Line line = null; + if (p1 != null && p2 != null) { + line = new Line(p1, p2); + canvas.add(line); + } + repaint(); + return line; + } + + public void paint(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + g2.setPaint(BACKGROUND); + g2.fill(new Rectangle2D.Float(0f, 0f, (float)g2.getClipBounds().width, (float)g2.getClipBounds().height)); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + canvas.paint(g2); + } + + + int lastX, lastY; + int pressX, pressY; + + FigureElement first = null; + Point point1 = null; + + public void mousePressed(MouseEvent e){ + int x = e.getX(), y = e.getY(); + pressX = lastX = x; pressY = lastY = y; + first = findFigureElement(x, y); + if (first == null) { + point1 = addPoint(x, y); + } + } + + public void mouseDragged(MouseEvent e) { + int x = e.getX(), y = e.getY(), dx = lastX-x, dy = lastY-y; + lastX = x; + lastY = y; + if (first == null) { + Line line = addLine(point1, new Point(x, y)); + if (line != null) { + canvas.add(line.getP2()); + first = line.getP2(); + canvas.add(line); + } + } else { + first.move(-dx, -dy); + } + repaint(); + } + + public void mouseReleased(MouseEvent e){ + mouseDragged(e); + first = null; + point1 = null; + } + + + public void mouseMoved(MouseEvent e){} + public void mouseClicked(MouseEvent e){} + public void mouseExited(MouseEvent e){} + public void mouseEntered(MouseEvent e){} + + private FigureElement findFigureElement(int x, int y) { + Point2D p = new Point2D.Float((float)x, (float)y); + for (Iterator i = canvas.members(); i.hasNext(); ) { + FigureElement fe = (FigureElement)i.next(); + if (fe.contains(p)) return fe; + } + return null; + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/gui/LogAdapter.java b/docs/modules/ROOT/pages/teaching/exercises/figures/gui/LogAdapter.java new file mode 100644 index 000000000..dbacd37ca --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures.gui; + +import support.Log; + +aspect LogAdapter { + + before(String s): call(void Log.log(String)) && args(s) { + if (Main.panel != null) { + Main.panel.cp.println(s); + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures/gui/Main.java b/docs/modules/ROOT/pages/teaching/exercises/figures/gui/Main.java new file mode 100644 index 000000000..23330ca8a --- /dev/null +++ b/docs/modules/ROOT/pages/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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package figures.gui; + +import javax.swing.*; +import support.Log; + +public class Main { + static FigurePanel panel; + + public static void main(String[] args) { + JFrame figureFrame = new JFrame("Figure Editor"); + panel = new FigurePanel(); + figureFrame.setContentPane(panel); + figureFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + figureFrame.pack(); + figureFrame.setVisible(true); + } + +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures_classes.png b/docs/modules/ROOT/pages/teaching/exercises/figures_classes.png Binary files differnew file mode 100644 index 000000000..0e3c65065 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/figures_classes.png diff --git a/docs/modules/ROOT/pages/teaching/exercises/figures_classes.svg b/docs/modules/ROOT/pages/teaching/exercises/figures_classes.svg new file mode 100644 index 000000000..1e2587a82 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/figures_classes.svg @@ -0,0 +1,298 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 20001102//EN' 'http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd'> +<svg xmlns="http://www.w3.org/2000/svg" width="1007" height="675"> +<rect x="148" y="14" width="148" height="108" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="148" y="14" width="147" height="107" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="149" y1="122" x2="296" y2="122" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="296" y1="15" x2="296" y2="121" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="148" y="14" width="148" height="19" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="148" y="14" width="147" height="18" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="189" y="29" style="font-family:Dialog; font-size:10;"> +<<Interface>></text> +<rect x="148" y="32" width="148" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="148" y="32" width="147" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="187" y="47" style="font-family:Dialog; font-size:10;"> +FigureElement</text> +<rect x="149" y="32" width="146" height="2" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="149" y="32" width="145" height="1" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="148" y="52" width="148" height="70" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="148" y="52" width="147" height="69" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="150" y="68" style="font-family:Dialog; font-size:10; font-style:italic;"> +move(dx: int,dy: int) : void</text> +<text x="150" y="85" style="font-family:Dialog; font-size:10; font-style:italic;"> +getBounds() : Rectangle</text> +<text x="150" y="102" style="font-family:Dialog; font-size:10; font-style:italic;"> +contains(p: Point2D) : boolean</text> +<text x="150" y="119" style="font-family:Dialog; font-size:10; font-style:italic;"> +paint(g2: Graphics2D) : void</text> +<rect x="14" y="202" width="148" height="159" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="14" y="202" width="147" height="158" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="15" y1="361" x2="162" y2="361" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="162" y1="203" x2="162" y2="360" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="14" y="202" width="148" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="14" y="202" width="147" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="38" y="217" style="font-family:Dialog; font-size:10; font-style:italic;"> +ShapeFigureElement</text> +<rect x="14" y="222" width="148" height="18" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="14" y="222" width="147" height="17" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<rect x="14" y="239" width="148" height="122" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="14" y="239" width="147" height="121" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="16" y="255" style="font-family:Dialog; font-size:10; font-style:italic;"> +move(dx: int,dy: int) : void</text> +<text x="16" y="272" style="font-family:Dialog; font-size:10; font-style:italic;"> +getShape() : Shape</text> +<text x="16" y="289" style="font-family:Dialog; font-size:10;"> +getBounds() : Rectangle</text> +<text x="16" y="306" style="font-family:Dialog; font-size:10;"> +contains(p: Point2D) : boolean</text> +<text x="16" y="323" style="font-family:Dialog; font-size:10;"> +getLineColor() : Color</text> +<text x="16" y="340" style="font-family:Dialog; font-size:10;"> +getFillColor() : Color</text> +<text x="16" y="357" style="font-family:Dialog; font-size:10;"> +paint(g2: Graphics2D) : void</text> +<rect x="242" y="202" width="188" height="192" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="242" y="202" width="187" height="191" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="243" y1="394" x2="430" y2="394" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="430" y1="203" x2="430" y2="393" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="242" y="202" width="188" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="242" y="202" width="187" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="321" y="217" style="font-family:Dialog; font-size:10;"> +Group</text> +<rect x="242" y="222" width="188" height="172" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="242" y="222" width="187" height="171" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="244" y="238" style="font-family:Dialog; font-size:10;"> +<<create>> Group(first: FigureElement)</text> +<text x="244" y="255" style="font-family:Dialog; font-size:10;"> +add(fe: FigureElement) : void</text> +<text x="244" y="272" style="font-family:Dialog; font-size:10;"> +members() : Iterator</text> +<text x="244" y="289" style="font-family:Dialog; font-size:10;"> +move(dx: int,dy: int) : void</text> +<text x="244" y="306" style="font-family:Dialog; font-size:10;"> +setIdentifier(identifier: String) : void</text> +<text x="244" y="323" style="font-family:Dialog; font-size:10;"> +toString() : String</text> +<text x="244" y="340" style="font-family:Dialog; font-size:10;"> +getBounds() : Rectangle</text> +<text x="244" y="357" style="font-family:Dialog; font-size:10;"> +contains(p: Point2D) : boolean</text> +<text x="244" y="374" style="font-family:Dialog; font-size:10;"> +paint(g2: Graphics2D) : void</text> +<text x="244" y="391" style="font-family:Dialog; font-size:10;"> +size() : int</text> +<rect x="14" y="490" width="141" height="158" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="14" y="490" width="140" height="157" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="15" y1="648" x2="155" y2="648" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="155" y1="491" x2="155" y2="647" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="14" y="490" width="141" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="14" y="490" width="140" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="72" y="505" style="font-family:Dialog; font-size:10;"> +Point</text> +<rect x="14" y="510" width="141" height="138" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="14" y="510" width="140" height="137" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="16" y="526" style="font-family:Dialog; font-size:10;"> +<<create>> Point(x: int,y: int)</text> +<text x="16" y="543" style="font-family:Dialog; font-size:10;"> +getX() : int</text> +<text x="16" y="560" style="font-family:Dialog; font-size:10;"> +getY() : int</text> +<text x="16" y="577" style="font-family:Dialog; font-size:10;"> +setX(x: int) : void</text> +<text x="16" y="594" style="font-family:Dialog; font-size:10;"> +setY(y: int) : void</text> +<text x="16" y="611" style="font-family:Dialog; font-size:10;"> +move(dx: int,dy: int) : void</text> +<text x="16" y="628" style="font-family:Dialog; font-size:10;"> +toString() : String</text> +<text x="16" y="645" style="font-family:Dialog; font-size:10;"> +getShape() : Shape</text> +<rect x="259" y="474" width="177" height="158" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="259" y="474" width="176" height="157" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="260" y1="632" x2="436" y2="632" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="436" y1="475" x2="436" y2="631" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="259" y="474" width="177" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="259" y="474" width="176" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="337" y="489" style="font-family:Dialog; font-size:10;"> +Line</text> +<rect x="259" y="494" width="177" height="138" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="259" y="494" width="176" height="137" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="261" y="510" style="font-family:Dialog; font-size:10;"> +<<create>> Line(p1: Point,p2: Point)</text> +<text x="261" y="527" style="font-family:Dialog; font-size:10;"> +getP1() : Point</text> +<text x="261" y="544" style="font-family:Dialog; font-size:10;"> +getP2() : Point</text> +<text x="261" y="561" style="font-family:Dialog; font-size:10;"> +move(dx: int,dy: int) : void</text> +<text x="261" y="578" style="font-family:Dialog; font-size:10;"> +toString() : String</text> +<text x="261" y="595" style="font-family:Dialog; font-size:10;"> +contains(p: Point2D) : boolean</text> +<text x="261" y="612" style="font-family:Dialog; font-size:10;"> +getLine2D() : Line2D</text> +<text x="261" y="629" style="font-family:Dialog; font-size:10;"> +getShape() : Shape</text> +<rect x="492" y="474" width="243" height="175" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="492" y="474" width="242" height="174" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="493" y1="649" x2="735" y2="649" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="735" y1="475" x2="735" y2="648" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="492" y="474" width="243" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="492" y="474" width="242" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="604" y="489" style="font-family:Dialog; font-size:10;"> +Box</text> +<rect x="492" y="494" width="243" height="155" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="492" y="494" width="242" height="154" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="494" y="510" style="font-family:Dialog; font-size:10;"> +<<create>> Box(x0: int,y0: int,width: int,height: int)</text> +<text x="494" y="527" style="font-family:Dialog; font-size:10;"> +getP0() : Point</text> +<text x="494" y="544" style="font-family:Dialog; font-size:10;"> +getP1() : Point</text> +<text x="494" y="561" style="font-family:Dialog; font-size:10;"> +getP2() : Point</text> +<text x="494" y="578" style="font-family:Dialog; font-size:10;"> +getP3() : Point</text> +<text x="494" y="595" style="font-family:Dialog; font-size:10;"> +move(dx: int,dy: int) : void</text> +<text x="494" y="612" style="font-family:Dialog; font-size:10;"> +checkBoxness() : void</text> +<text x="494" y="629" style="font-family:Dialog; font-size:10;"> +toString() : String</text> +<text x="494" y="646" style="font-family:Dialog; font-size:10;"> +getShape() : Shape</text> +<rect x="815" y="474" width="178" height="158" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="815" y="474" width="177" height="157" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="816" y1="632" x2="993" y2="632" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="993" y1="475" x2="993" y2="631" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="815" y="474" width="178" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="815" y="474" width="177" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="873" y="489" style="font-family:Dialog; font-size:10;"> +SlothfulPoint</text> +<rect x="815" y="494" width="178" height="138" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="815" y="494" width="177" height="137" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="817" y="510" style="font-family:Dialog; font-size:10;"> +<<create>> SlothfulPoint(x: int,y: int)</text> +<text x="817" y="527" style="font-family:Dialog; font-size:10;"> +getX() : int</text> +<text x="817" y="544" style="font-family:Dialog; font-size:10;"> +getY() : int</text> +<text x="817" y="561" style="font-family:Dialog; font-size:10;"> +setX(x: int) : void</text> +<text x="817" y="578" style="font-family:Dialog; font-size:10;"> +setY(y: int) : void</text> +<text x="817" y="595" style="font-family:Dialog; font-size:10;"> +move(dx: int,dy: int) : void</text> +<text x="817" y="612" style="font-family:Dialog; font-size:10;"> +toString() : String</text> +<text x="817" y="629" style="font-family:Dialog; font-size:10;"> +getShape() : Shape</text> +<rect x="630" y="86" width="139" height="108" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="630" y="86" width="138" height="107" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="631" y1="194" x2="769" y2="194" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<line x1="769" y1="87" x2="769" y2="193" style="fill:#1a1a1a; stroke:#1a1a1a; stroke-width:1"/> +<rect x="630" y="86" width="139" height="21" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="630" y="86" width="138" height="20" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<text x="690" y="101" style="font-family:Dialog; font-size:10;"> +Log</text> +<rect x="630" y="106" width="139" height="18" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="630" y="106" width="138" height="17" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="632" y1="123" x2="678" y2="123" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<text x="632" y="122" style="font-family:Dialog; font-size:10;"> +data : List</text> +<rect x="630" y="123" width="139" height="71" style="fill:#ffffff; stroke:#ffffff; stroke-width:1"/> +<rect x="630" y="123" width="138" height="70" style="fill:#ffffff; stroke:#000000; stroke-width:1"/> +<line x1="632" y1="140" x2="767" y2="140" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<text x="632" y="139" style="font-family:Dialog; font-size:10;"> +traceObject(o: Object) : void</text> +<line x1="632" y1="157" x2="720" y2="157" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<text x="632" y="156" style="font-family:Dialog; font-size:10;"> +log(s: String) : void</text> +<line x1="632" y1="174" x2="700" y2="174" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<text x="632" y="173" style="font-family:Dialog; font-size:10;"> +getData() : List</text> +<line x1="632" y1="191" x2="691" y2="191" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<text x="632" y="190" style="font-family:Dialog; font-size:10;"> +clear() : void</text> +<line x1="98" y1="202" x2="98" y2="197" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="98" y1="192" x2="98" y2="187" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="98" y1="182" x2="98" y2="177" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="98" y1="172" x2="98" y2="167" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="98" y1="162" x2="98" y2="157" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="98" y1="154" x2="103" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="108" y1="154" x2="113" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="118" y1="154" x2="123" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="128" y1="154" x2="133" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="138" y1="154" x2="143" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="148" y1="154" x2="153" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="158" y1="154" x2="163" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="168" y1="154" x2="173" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="178" y1="154" x2="183" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="188" y1="154" x2="193" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="198" y1="154" x2="203" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="208" y1="154" x2="213" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="218" y1="154" x2="223" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="228" y1="154" x2="232" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="154" x2="232" y2="149" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="144" x2="232" y2="139" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="134" x2="232" y2="129" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="124" x2="232" y2="122" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="232,123 239,135 225,135"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="232,123 239,135 225,135"/> +<line x1="346" y1="202" x2="346" y2="197" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="346" y1="192" x2="346" y2="187" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="346" y1="182" x2="346" y2="177" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="346" y1="172" x2="346" y2="167" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="346" y1="162" x2="346" y2="157" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="346" y1="154" x2="341" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="336" y1="154" x2="331" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="326" y1="154" x2="321" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="316" y1="154" x2="311" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="306" y1="154" x2="301" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="296" y1="154" x2="291" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="286" y1="154" x2="281" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="276" y1="154" x2="271" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="266" y1="154" x2="261" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="256" y1="154" x2="251" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="246" y1="154" x2="241" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="236" y1="154" x2="232" y2="154" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="154" x2="232" y2="149" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="144" x2="232" y2="139" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="134" x2="232" y2="129" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="232" y1="124" x2="232" y2="122" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="232,123 239,135 225,135"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="232,123 239,135 225,135"/> +<polyline style="fill:none; stroke:#000000; stroke-width:1" points="84,490 84,442 88,442 88,361"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="88,362 95,374 81,374"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="88,362 95,374 81,374"/> +<polyline style="fill:none; stroke:#000000; stroke-width:1" points="323,474 323,442 88,442 88,361"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="88,362 95,374 81,374"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="88,362 95,374 81,374"/> +<polyline style="fill:none; stroke:#000000; stroke-width:1" points="613,474 613,442 88,442 88,361"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="88,362 95,374 81,374"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="88,362 95,374 81,374"/> +<polyline style="fill:none; stroke:#000000; stroke-width:1" points="904,474 904,442 88,442 88,361"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="88,362 95,374 81,374"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="88,362 95,374 81,374"/> +<polyline style="fill:none; stroke:#000000; stroke-width:1" points="296,202 296,122"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="296,202 291,192 296,182 301,192"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="296,202 291,192 296,182 301,192"/> +<line x1="303" y1="135" x2="296" y2="123" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="289" y1="135" x2="296" y2="123" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<text x="279" y="193" style="font-family:Dialog; font-size:10;"> +*</text> +<polyline style="fill:none; stroke:#000000; stroke-width:1" points="155,566 259,566"/> +<line x1="167" y1="559" x2="155" y2="566" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="167" y1="573" x2="155" y2="566" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="258,566 248,571 238,566 248,561"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="258,566 248,571 238,566 248,561"/> +<text x="241" y="557" style="font-family:Dialog; font-size:10;"> +2</text> +<polyline style="fill:none; stroke:#000000; stroke-width:1" points="155,646 492,646"/> +<line x1="167" y1="639" x2="155" y2="646" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<line x1="167" y1="653" x2="155" y2="646" style="fill:#000000; stroke:#000000; stroke-width:1"/> +<polygon style="fill:#ffffff; stroke:#ffffff; stroke-width:1" points="491,646 481,651 471,646 481,641"/> +<polygon style="fill:#ffffff; stroke:#000000; stroke-width:1" points="491,646 481,651 471,646 481,641"/> +<text x="474" y="637" style="font-family:Dialog; font-size:10;"> +4</text> +</svg> diff --git a/docs/modules/ROOT/pages/teaching/exercises/guibase.lst b/docs/modules/ROOT/pages/teaching/exercises/guibase.lst new file mode 100644 index 000000000..0a9371462 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/guibase.lst @@ -0,0 +1,5 @@ +-argfile +base.lst +figures/gui/FigurePanel.java +figures/gui/Main.java +figures/gui/LogAdapter.java
\ No newline at end of file diff --git a/docs/modules/ROOT/pages/teaching/exercises/index.html b/docs/modules/ROOT/pages/teaching/exercises/index.html new file mode 100644 index 000000000..5212f6e42 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/index.html @@ -0,0 +1,689 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + +<!-- This file represents the Exercises for the hands-on AspectJ + tutorial. It is commonly checked into CVS with identifying + information for the latest conference (such as presenters + and publication information). + + When you use it for your own purposes, don't forget to + modify at the very least anything that says + id="copyright" or class="presenter". If you're in an A4 + country, don't forget to modify the paper size. + + The gif included at the end is somewhat fragile, + so be careful with different paper sizes. + + TODO: There is currently something weird about PDF generation + from this: If generated from a windows machine, it will + generate mac-unfriendly PDF because of the requested windows + font. If the PDF is only used for immediate printing, + that's fine, but if it's used for distribution, bad. +--> + +<head> + <title>Hands-on Programming with AspectJ® — Exercises</title> + <style type="text/css"> +div.instruction { padding: 0.5em; border-width: 1px; border-style: solid } +body { background-color: #FFF; margin: 2em } +body { font-family: "Gill Sans MT", "Gill sans", "Trebuchet ms", Verdana, sans-serif; } +.newpage { page-break-before: always } +pre { margin-left: 1em; border-left-style: solid; border-width: 1px; padding-left: 1em;} +h2 { margin-top: 4ex; } +h3 { margin-top: 4ex; border-bottom-style: solid; border-width: 1px } +.presenter { text-align: right } +@page { + size: 8.5in 11in; + margin: 3in; + marks: cross +} +@media print { + body { font-size: 10pt } + #copyright { + font-family: "Times New Roman", "Times Roman", fixed; + font-size: 8pt; + display: normal; + position: absolute; + bottom: 1in; + border-style: none + } +} +@media screen { + #copyright { display: none } +} + </style> +</head> + +<body> + +<h1>Hands-on Programming with AspectJ<sup>®</sup></h1> + +<div class="presenter">Erik Hilsdale</div> +<div class="presenter">Mik Kersten</div> +<div class="presenter">http://www.eclipse.com/aspectj</div> + +<h2>Overview</h2> + +<p> In this tutorial you will solve some canonical programming +tasks using AspectJ. The tasks progress from writing +non-functional, development-only aspects to writing aspects that +augment a deployed program with crosscutting features. This +follows the same progression most users see in their own adoption +of AspectJ. </p> + +<p> Since this is a hands-on tutorial, you will be working with a +live AspectJ distribution. The example code we will be working +with is a simple figure editor, along with JUnit tests for each +exercise. We will break up into groups of two to three people +per computer to foster discussion within the group as well as +with the presenters. </p> + +<p> If you have a laptop running a recent version of Windows, +MacOS or Linux, feel free to bring it along. We will provide CDs +and other installation media for a standalone AspectJ system, +including the figure editor code these exercises are based on and +unit tests for the exercises. If you don't have a laptop with +you, don't worry about it. </p> + +<p> These notes consist of four sections of exercises, a quick +reference to AspectJ syntax, and a UML diagram of a figure editor +program. </p> + +<div class="instruction"> If you receive these tutorial notes +early, feel free to have a quick look, especially at the UML +diagram and quick reference. But you'll be cheating yourself if +you try to do the exercises early; you'll learn a lot more by +working through it in groups during the tutorial proper. </div> + +<!-- +This space is used for a copyright that appears on the +bottom of the _printed_ page. It's suppressed when viewed on +a computer screen by the stylesheet. + +<div id="copyright"> +Copyright is held by the author/owner(s). <br /> +OOPSLA’04, October 24-28, 2004, Vancouver, British Columbia, Canada <br /> +2004 ACM 04/0010 +</div> +--> + +<h3 class="newpage">Command-line usage</h3> + +<p> While the AspectJ system is well integrated with a number of +IDEs, it can also be used as a command-line compiler. The +standalone package we provide (containing the tests, the base +code, JUnit, and a distribution of AspectJ) needs 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 <code>setpaths</code> or <code>setpaths.bat</code>, as +appropriate. +</p> + +<p> Each time you open a new shell window run +<code>setpaths.bat</code> or <code>source setpaths</code> to +export some other needed environment variables. </p> + +<p> In general, all the files in the program are listed in +<code>base.lst</code>, 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 +<code>base.lst</code>, either in an IDE or with </p> + +<pre> +$ ajc -argfile base.lst +</pre> + +<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> + +<pre> +> copy answers/Answer.java answers/2a.java (Windows) +$ cp answers/Answer.java answers/2a.java (Unix) +</pre> + +<p> After building the system, you should invoke Java on the compiled +test class. On the command-line, this this would be </p> + +<pre> +$ java tests.Test2a +</pre> + +<p> The default test, <code>tests.CoreTest</code>, performs some +rudimentary tests on figure elements, and so is a useful test to run +periodically. You should also look at the JUnit tests for each +exercise as you do it. </p> + +<p> Again, we will be looking at solutions and having discussion, +which is much more difficult without incremental solutions. So +when you go from one exercise to the next, <strong>save your +work</strong> in a file before going on to the next exercise +even if you plan to duplicate some code. </p> + +<div class="instruction"> When we give examples of execution in +these exercises we will show the command-line use, but of course +you should use the appropriate compile and execute tools if you +are using the AspectJ browser, Emacs, or Eclipse. </div> + +<!-- ============================== --> + +<h2 class="newpage">1. Static Invariants</h2> + +<p> The easiest way to get started with AspectJ is to use it to +enforce static invariants. +</p> + +<h3>1.a. Find old tracing</h3> + +<div class="instruction"> <strong>Sample Exercise</strong>: The +main point of this exercise is to make sure your configuration +works. Type in the answer below into your answer file, make sure +you get the desired compile-time error, remove the offending +line, and make sure you pass the JUnit test. </div> + +<p> <strong>Task:</strong> Signal an error for calls to +<code>System.out.println</code>. +</p> + +<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 far longer than is necessary. Type in the aspect +below to signal an error at compile time if this mistake is made. +</p> + +<p> <strong>Answer:</strong> +</p> + +<pre> +package answers; + +import figures.*; + +aspect Answer1a { + declare error + : get(java.io.PrintStream System.out) && within(figures..*) + : "illegal access to System.out"; +} +</pre> + +<p> When you use this on the given system, you'll find one incorrect +trace in <code>SlothfulPoint</code>. +</p> + +<pre> +$ ajc -argfile base.lst +./figures/SlothfulPoint.java:38 illegal access to System.out + +1 error +</pre> + +<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> + +<p> After you have successfully used this aspect, edit your +program to remove the illegal tracing call. </p> + +<p> Make sure your program still passes the JUnit test +<code>tests.CoreTest</code> (which it should also pass at the beginning of +all exercises) before continuing. </p> + +<pre> +$ java tests.CoreTest +.... +Time: 0.03 + +OK (4 tests) +</pre> + +<h3 class="newpage">1.b. Mandate setters</h3> + +<p> <strong>Task:</strong> Signal a warning for assignments outside +of setter methods. </p> + +<p> <strong>Tools:</strong> <code>set</code>, <code>withincode</code>, +the <code>void set*(..)</code> pattern +</p> + +<p> One common coding convention is that no private field should +be assigned to outside of setter methods. Write an aspect to +signal a warning at compile time for these illegal assignment +expressions. </p> + +<p> This is going to look like +</p> + +<pre> +aspect A { + declare warning: <em><pointcut here></em> : "bad field set"; +} +</pre> + +<p> where the pointcut picks out join points of private field sets +outside of setter methods. "Outside", here, means that the code for +the assignment is outside the <em>text</em> of the setter. + +<p> Make sure your program still passes the JUnit test +<code>tests.CoreTest</code> before continuing. Make sure you get eleven +warnings from this. Wait to fix them until the next exercise. </p> + +<h3>1.c. Refine setters mandate</h3> + +<p> <strong>Task:</strong> Allow assignmnents inside of constructors. +</p> + +<p> <strong>Tools:</strong> the <code>new(..)</code> pattern</p> + +<p> Look at some of the warnings from the previous exercise. Notice +that a lot of them are from within constructors. Actually, the common +coding convention is that no private field should be assigned to outside of +setter methods <em>or constructors</em>. Modify your answer 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:37 bad field set +.\figures\Point.java:38 bad field set + +2 errors +</pre> + +<p>Rewrite these two occurrences so as not to violate +the convention. Make sure your program still passes the JUnit test +<code>tests.CoreTest</code> before continuing. </p> + +<div class="instruction"> Congratulations, you've taken your +first steps. At this point, check the people to your left and +right. If they're stuck somewhere, see if you can help them. +Try to resist moving on to the next section until we discuss +solutions as a group. </div> + +<!-- ============================== --> + +<h2 class="newpage">2. Dynamic invariants</h2> + +<p> The next step in AspectJ adoption is often to augment a test suite +by including additional dynamic tests. +</p> + +<div class="instruction"> Tutorial attendees typically progress +at different speeds through these exercises. Throughout this +tutorial, if you finish early, see what the people around you are +doing and if they need help. Don't help them out of charity, +help them out of naked self-interest—we promise you'll learn a +lot about using AspectJ by explaining it. </div> + +<h3>2.a. Check a simple precondition</h3> + +<div class="instruction"> <strong>Sample Exercise</strong>: We've +provided the answer to this exercise to get you started. Feel +free to think a bit, but don't get stuck on this one. </div> + +<p> <strong>Task:</strong> Pass <code>tests.Test2a</code>. +</p> + +<p> <strong>Tools:</strong> <code>args</code>, <code>before</code> +</p> + +<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 less than zero. </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> + +<pre> +$ java tests.Test2a +.F..F.... +Time: 0.04 +There were 2 failures: +1) testTooSmall(tests.Test2a)junit.framework.AssertionFailedError: should have thrown IllegalArgumentException +2) testMove(tests.Test2a)junit.framework.AssertionFailedError: should have thrown IllegalArgumentException + +FAILURES!!! +Tests run: 7, Failures: 2, Errors: 0 +</pre> + +<p> But after compiling in the aspect... +</p> + +<pre> +$ ajc -argfile base.lst answers/Answer.java + +$ java tests.Test2a +....... +Time: 0.04 + +OK (7 tests) +</pre> + +<p> <strong>Answer:</strong> +</p> + +<pre> +package answers; + +import figures.*; + +aspect Answer2a { + before(int newValue): set(int Point.*) && args(newValue) { + if (newValue < 0) { + throw new IllegalArgumentException("too small"); + } + } +} +</pre> + +<h3>2.b. Check another precondition</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test2b</code>. </p> + +<p> <strong>Tools: </strong> <code>call</code>. +</p> + +<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. </p> + +<p> Look at <code>tests/Test2b.java</code> to see exactly what we're +testing for. </p> + +<h3>2.c. Check yet another precondition</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test2c</code>. </p> + +<p> <strong>Tools:</strong> <code>target</code> +</p> + +<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> + +<h3>2.d. Assure input</h3> + +<p> <strong>Task: </strong> Pass <code>tests.Test2d</code>. +</p> + +<p> <strong>Tools: </strong> around advice +</p> + +<p> Instead of throwing an exception when one of <code>Point</code>'s +<code>int</code> fields is set to a negative value, write an aspect +to trim the value to zero. 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. </p> + +<p> This is going to look something like +</p> + +<pre> +aspect A { + void around(int val): <var><Pointcut></var> { + <var><Do something with val></var> + proceed(val); + } +} +</pre> + +<h3 class="newpage">2.e. Check a postcondition</h3> + +<p> <strong>Task: </strong> Pass <code>tests.Test2e</code> +</p> + +<p> <strong>Tools: </strong> around advice +</p> + +<p> A postcondition of a <code>Point</code>'s <code>move</code> +operation is that the <code>Point</code>'s coordinates should change. +If a call to move didn't actually move a point by the desired +offset, then the point is in an illegal state and so an +<code>IllegalStateException</code> should be thrown. +</p> + +<p> Note that because we're dealing with how the coordinates change +during move, we need some way of getting access to the coordinates +both before <em>and</em> after the move, in one piece of advice. </p> + +<h3>2.f. Check another postcondition</h3> + +<p> <strong>Task: </strong> Pass <code>tests.Test2f</code> +</p> + +<p> <strong>Tools:</strong> the <code> Rectangle(Rectangle)</code> +constructor, the <code>Rectangle.translate(int, int)</code> method. +</p> + +<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 general +<code>move</code> operation on a figure element 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> + +<!-- ============================== --> + +<h2 class="newpage">3. Tracing</h2> + +<p> Tracing is one of the classic AspectJ applications, and is often +the first where AspectJ is used on deployed code. +</p> + +<h3>3.a. Simple tracing</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test3a</code>.</p> + +<p> <strong>Tools:</strong> + <code>Log.write(String)</code>, + <code>thisJoinPoint.toString()</code>, + <code>execution</code>, + <code>within</code> +</p> + +<p> Write an aspect to log the execution of all public methods +in the figures package. To do this, use the utility class +<code>Log</code> (this is in the <code>support</code> package, so +remember to import it into your answer aspect). Write a message +into the log with the static <code>write(String)</code> method.</p> + +<h3>3.b. Exposing a value</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test3b</code>.</p> + +<p> <strong>Tools:</strong> <code>target</code> +</p> + +<p> AspectJ can expose the target object at a join point for tracing. +In this exercise, you will print not only the join point information, +but also the target object, with the form +</p> + +<pre> +<em>thisJoinPointInfo</em> at <em>targetObject</em> +</pre> + + +<h3>3.c. More specialized logging</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test3c</code>.</p> + +<p> <strong>Tools:</strong> <code>args</code>. +</p> + +<p> Write an aspect to log whenever a <code>Point</code> is added to a +group. The <code>args</code> pointcut allows you to select join points +based on the type of a parameter to a method call. </p> + +<p> Look at the test case to see the trace message we expect you +to write in the log. +</p> + +<h3 class="newpage">3.d. Logging extended to checking an invariant</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test3d</code>.</p> + +<p> <strong>Tools:</strong> <code>inter-type field declaration</code> +</p> + +<p> Make sure that a <code>Point</code> is never added to more +than one <code>Group</code>. To do so, associate a boolean flag +with each <code>Point</code> using an inter-type declaration, +such as </p> + +<pre> +boolean Point.hasBeenAdded = false; +</pre> + +<p> Check and set this flag with the same kind of advice from your +answer to problem (c). Throw an <code>IllegalStateException</code> if +the point has already been added. +</p> + +<h3>3.e. Better error messages for 3.d.</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test3e</code>.</p> + +<p> Extend your solution to problem (d) by using the string +representation of the Point's containing group as the <code>msg</code> +part of the <code>IllegalStateException</code>. </p> + +<!-- ============================== --> + +<h2 class="newpage">4. Caching</h2> + +<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> + +<div class="instruction"> <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. </div> + +<h3>4.a. Make a constant override</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test4a</code>.</p> + +<p> <strong>Tools:</strong> <code>around</code>, + <code>FigureElement.MAX_BOUNDS</code> +</p> + +<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. The entire canvas is returned +by the static method <code>FigureElement.MAX_BOUNDS</code>. +</p> + +<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> + +<h3>4.b. Make a constant cache</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test4b</code>. +</p> + +<p> <strong>Tools:</strong> inter-type field. +</p> + +<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> + + +<h3>4.c. Invalidate, part 1</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test4c</code>. +</p> + +<p> <strong>Tools:</strong> <code>before</code> +</p> + +<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> + +<h3 class="newpage">4.d. Invalidate, part 2</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test4d</code>.</p> + +<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> + +<h3>4.e. Invalidate, part 3</h3> + +<p> <strong>Task:</strong> Pass <code>tests.Test4e</code>.</p> + +<p> <strong>Tools:</strong> <em>You're on you're own</em></p> + +<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> + +<div class="instruction"> + +<p> Congratulations! Not only have you learned about how to +program in AspectJ, you have worked through exercises paralleling +a common AspectJ adoption strategy. You should be able to +pick up AspectJ and use it to improve your own software's +crosscutting modularity. </p> + +<p> You can find the current binaries, source, documentation and +an active user community for AspectJ at</p> + + <blockquote> + https://www.eclipse.org/aspectj + </blockquote> + +</div> + +<img style="newpage" src="figures_classes.png" height="900" alt="" /> + +</body> </html> diff --git a/docs/modules/ROOT/pages/teaching/exercises/install.txt b/docs/modules/ROOT/pages/teaching/exercises/install.txt new file mode 100644 index 000000000..ccb2b9e71 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/install.txt @@ -0,0 +1,63 @@ +0. Install + + Now get the directory "aj-@aj.event@/". Just copy the + "aj-@aj.event@/" directory from the provided CD. + + If you're running a Windows machine, we recommend you copy into + "c:\". If you're running your favorite Unix (we've had success under + Linux and MacOS X), we recommend you install into "~\". + +1. Configure + + Our installation is fairly well self-contained, but it does need to know + where Java lives. To do this you must set the environment variable named + JAVA_HOME. This variable should point to something like + + c:\apps\jdk1.3.1_04 + /usr/java + /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + + depending on your system. You may either do this globally, or you may + edit the appropriate setpaths script: + + setpaths.bat (under Windows) + setpaths.sh (if you run bash/sh/ksh, like most Linux setups) + setpaths.csh (if you run csh, like most MacOS X setups) + + Also, if you installed into a directory other than "c:\" or "~/", then you + need to change the EXTRACTION environment variable in the setpaths script. + +2. Test + + Open a new command shell and change to the "aj-@aj.event@/" directory. + + We have provided a "setpaths" script to set permissions and various paths + variables, so run this script: + + > setpaths.bat (under Windows) + > source setpaths.sh (if you run bash/sh/ksh, like most Linux setups) + > source setpaths.csh (if you run csh, like most MacOS X setups) + + You must remember to run this script every time you open a new command + shell. + + Now, compile the core system with ajc: + + > ajc -argfile guibase.lst + + This should compile the figures application (source code in the figures + directory) as well as a single unit test (source code in the tests + directory). + + See if the compile was successful by running the gui figures app you just + compiled: + + > java figures.gui.Main + + And, after quitting out of the gui figures app, run the unit test: + + > java tests.Test + .... + Time: 0.076 + + OK (4 tests) diff --git a/docs/modules/ROOT/pages/teaching/exercises/junit.jar b/docs/modules/ROOT/pages/teaching/exercises/junit.jar Binary files differnew file mode 100644 index 000000000..674d71e89 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/junit.jar diff --git a/docs/modules/ROOT/pages/teaching/exercises/plugins/index.adoc b/docs/modules/ROOT/pages/teaching/exercises/plugins/index.adoc new file mode 100644 index 000000000..1cdf0fbc1 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/plugins/index.adoc @@ -0,0 +1,19 @@ +== Exercises plugin for the tutorial + +Download the appropriate version and unzip it in your eclipse\plugins +directory: + +[cols=",",] +|=== +|For Eclipse 3.0 with AJDT 1.1.12 +|https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.1.12.zip?rev=1.1&cvsroot=Technology_Project[org.aspectj.tutorial.exercises_1.1.12.zip] + +|For Eclipse 3.0 with AJDT 1.2.0M2 +|https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0M2.zip?rev=1.1&cvsroot=Technology_Project[org.aspectj.tutorial.exercises_1.2.0M2.zip] + +|For Eclipse 3.0 with AJDT 1.2.0 latest dev build +|https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_301_Dev.zip?rev=1.1&cvsroot=Technology_Project[org.aspectj.tutorial.exercises_1.2.0_301_Dev.zip] + +|For Eclipse 3.1M5 with AJDT 1.2.0 latest dev build +|https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_31M5_Dev.zip?rev=1.1&cvsroot=Technology_Project[org.aspectj.tutorial.exercises_1.2.0_31M5_Dev.zip] +|=== diff --git a/docs/modules/ROOT/pages/teaching/exercises/plugins/index.html b/docs/modules/ROOT/pages/teaching/exercises/plugins/index.html new file mode 100644 index 000000000..ef87c84c8 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/plugins/index.html @@ -0,0 +1,31 @@ +<html> +<head> +</head> +<body> +<h1>Exercises plugin for the tutorial</h1> + +<p>Download the appropriate version and unzip it in your eclipse\plugins directory:</p> +<table> +<tr> +<td>For Eclipse 3.0 with AJDT 1.1.12 </td> +<td><a href="https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.1.12.zip?rev=1.1&cvsroot=Technology_Project"> +org.aspectj.tutorial.exercises_1.1.12.zip</a></td> +</tr> +<tr> +<td>For Eclipse 3.0 with AJDT 1.2.0M2 </td> +<td><a href="https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0M2.zip?rev=1.1&cvsroot=Technology_Project"> +org.aspectj.tutorial.exercises_1.2.0M2.zip</a></td> +</tr> +<tr> +<td>For Eclipse 3.0 with AJDT 1.2.0 latest dev build </td> +<td><a href="https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_301_Dev.zip?rev=1.1&cvsroot=Technology_Project"> +org.aspectj.tutorial.exercises_1.2.0_301_Dev.zip</a></td> +</tr> +<tr> +<td>For Eclipse 3.1M5 with AJDT 1.2.0 latest dev build </td> +<td><a href="https://dev.eclipse.org/viewcvs/index.cgi/~checkout~/org.aspectj/modules/docs/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_31M5_Dev.zip?rev=1.1&cvsroot=Technology_Project"> +org.aspectj.tutorial.exercises_1.2.0_31M5_Dev.zip</a></td> +</tr> +</table> +</body> +</html> diff --git a/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.1.12.zip b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.1.12.zip Binary files differnew file mode 100644 index 000000000..674af9cd7 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.1.12.zip diff --git a/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0M2.zip b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0M2.zip Binary files differnew file mode 100644 index 000000000..90a4acc86 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0M2.zip diff --git a/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_301_Dev.zip b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_301_Dev.zip Binary files differnew file mode 100644 index 000000000..6c192738c --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_301_Dev.zip diff --git a/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_31M5_Dev.zip b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_31M5_Dev.zip Binary files differnew file mode 100644 index 000000000..3c817b274 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/plugins/org.aspectj.tutorial.exercises_1.2.0_31M5_Dev.zip diff --git a/docs/modules/ROOT/pages/teaching/exercises/pre-letter.txt b/docs/modules/ROOT/pages/teaching/exercises/pre-letter.txt new file mode 100644 index 000000000..4833beeb5 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/pre-letter.txt @@ -0,0 +1,130 @@ +Dear OOPSLA 2002 attendee; + +We have you listed as being registered for tutorial T40, +Aspect-oriented programming with AspectJ. We are excited about giving +this tutorial, and hope you will enjoy the presentation, exercises and +discussion we have prepared. + +As with our past tutorials of this form, in the afternoon we would +like to break the attendees into groups of two or three and work +through a number of AspectJ exercises together. + +We will be bringing media and making ourselves available during breaks +for help with setup, but in order to jump straight in and give you the +most we can from this tutorial, it would really help us if many of you +had an AspectJ environment installed early. + +This message contains basic instructions on where to get some needed +tools. These instructions will not take much time. + +If you are planning to bring a laptop to the tutorial, would you +please take the time to do the steps outlined in this message? + +If you're not planning to, you might want to install an AspectJ +environment on your desktop anyway and try the instructions below, so +you will be comfortable when we meet on Wednesday. + +[If you already have a working AspectJ environment and are familliar +with it, we still recommend that you upgrade to 1.0.6 and follow the +steps below] + +Thank you, and please don't hesitate to contact us (at +support@aspectj.org) if you have any questions. See you on +Wednesday... + +-Erik Hilsdale, + Jim Hugunin, + and the whole AspectJ Team + + +Getting Ready for T40, Aspect-oriented programming with AspectJ +-------------------------------------- + +Overview: + + 0. Install AspectJ + 1. Download JUnit and put it on your classpath + 2. Test your setup + +------------------------------ +0. AspectJ + +Download the AspectJ 1.0.6 from + + http://aspectj.org/dl + +You should definitly download and intstall the tools package and the +docs package. If you plan to use JBuilder, Forte/NetBeans, Emacs, or +Eclipse for your development, you should download the appropriate +plugin. + + +------------------------------ +1. JUnit + +We use the JUnit framework for testing our exercises. Download JUnit +from + + http://www.junit.org + +and place junit.jar on your CLASSPATH. + + +------------------------------ +2. Test your setup + +a. Create a file "Hello.java" with this class: + + class Hello { + public static void main(String[] args) { + System.err.println(getHelloString()); + } + public static String getHelloString() { + return "Hello, WORLD"; + } + } + +b. Compile the class with ajc and run it... + + > ajc Hello.java + > java Hello + Hello, WORLD + +c. Create a file "TestHello.java" with this class: + + public class TestHello extends junit.framework.TestCase { + public TestHello(String name) { + super(name); + } + public static void main(String[] args) { + junit.textui.TestRunner.run(TestHello.class); + } + public void testHello() { + assertEquals("Hello, OOPSLA", Hello.getHelloString()); + } + } + +d. Compile the class with ajc and run it... + + > ajc TestHello.java + > java TestHello + .F + Time: 0.01 + There was 1 failure: + 1) testHello(TestHello)junit.framework.ComparisonFailure: + expected:<...OOPSLA> but was:<...WORLD> + at TestHello.testHello(TestHello.java:9) + at TestHello.main(TestHello.java:6) + + FAILURES!!! + Tests run: 1, Failures: 1, Errors: 0 + +e. Oops... the test case seems to want a different string than the + tested class. Fix that, compile whichever file you changed with + ajc, run the tester again, and you're done. Thanks! + + > java TestHello + . + Time: 0 + + OK (1 test) diff --git a/docs/modules/ROOT/pages/teaching/exercises/scripts/ajbrowser b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajbrowser new file mode 100644 index 000000000..2f804efda --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajbrowser @@ -0,0 +1,3 @@ +#!/bin/sh + +"$JAVA_HOME/bin/java" -classpath "$ASPECTJ_HOME/lib/aspectjtools.jar:$JAVA_HOME/lib/tools.jar:$CLASSPATH" -Xmx64M org.aspectj.tools.ajbrowser.Main "$@" diff --git a/docs/modules/ROOT/pages/teaching/exercises/scripts/ajbrowser.bat b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajbrowser.bat new file mode 100644 index 000000000..dd717ccae --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajbrowser.bat @@ -0,0 +1,9 @@ +@echo off +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 +"%JAVA_HOME%\bin\java" -classpath "%ASPECTJ_HOME%\lib\aspectjtools.jar;%JAVA_HOME%\lib\tools.jar;%CLASSPATH%" -Xmx64M org.aspectj.tools.ajbrowser.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/docs/modules/ROOT/pages/teaching/exercises/scripts/ajc b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajc new file mode 100644 index 000000000..f8f45ee35 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajc @@ -0,0 +1,3 @@ +#!/bin/sh + +"$JAVA_HOME/bin/java" -classpath "$ASPECTJ_HOME/lib/aspectjtools.jar:$JAVA_HOME/lib/tools.jar:$CLASSPATH" -Xmx64M org.aspectj.tools.ajc.Main "$@" diff --git a/docs/modules/ROOT/pages/teaching/exercises/scripts/ajc.bat b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajc.bat new file mode 100644 index 000000000..ca51b07be --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/scripts/ajc.bat @@ -0,0 +1,9 @@ +@echo off +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 +"%JAVA_HOME%\bin\java" -classpath "%ASPECTJ_HOME%\lib\aspectjtools.jar;%JAVA_HOME%\lib\tools.jar;%CLASSPATH%" -Xmx64M org.aspectj.tools.ajc.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.bat b/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.bat new file mode 100644 index 000000000..390eec58a --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.bat @@ -0,0 +1,15 @@ +@echo off + +rem Change this to be the full path for this directory +set EXTRACTION=c:\aj-@aj.event@ + +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;%JAVA_HOME%\jre\lib\rt.jar diff --git a/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.csh b/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.csh new file mode 100644 index 000000000..276bbf4d1 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.csh @@ -0,0 +1,11 @@ +# this file should be sourced, NOT executed + +# Change this to be the full path for this directory +set EXTRACTION=$HOME/aj-@aj.event@ + +set ASPECTJ_HOME=$EXTRACTION/aspectj +set PATH=$ASPECTJ_HOME/bin:$PATH +set CLASSPATH=.:$ASPECTJ_HOME/lib/aspectjrt.jar:$EXTRACTION/junit.jar:$JAVA_HOME/jre/lib/rt.jar + +chmod a+x $ASPECTJ_HOME/bin/ajc +chmod a+x $ASPECTJ_HOME/bin/ajbrowser diff --git a/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.sh b/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.sh new file mode 100644 index 000000000..e944776ed --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/scripts/setpaths.sh @@ -0,0 +1,18 @@ +# this file should be sourced, NOT executed + +# Change this to be the full path for this directory +EXTRACTION=$HOME/aj-@aj.event@ + +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:$JAVA_HOME/jre/lib/rt.jar + +chmod a+x $ASPECTJ_HOME/bin/ajc +chmod a+x $ASPECTJ_HOME/bin/ajbrowser + diff --git a/docs/modules/ROOT/pages/teaching/exercises/setpaths b/docs/modules/ROOT/pages/teaching/exercises/setpaths new file mode 100644 index 000000000..2933d3a89 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/setpaths @@ -0,0 +1,14 @@ +#!/bin/sh + +# Change this to be the full path for this directory +EXTRACTION=$HOME/aj-oopsla + +if [ "$JAVA_HOME" = "" ] +then + echo Please remember to manually set $JAVA_HOME to + echo the location of your java installation +fi + +export ASPECTJ_HOME=$EXTRACTION/aspectj +export PATH=$ASPECTJ_HOME/bin:$PATH +export CLASSPATH=.:$ASPECTJ_HOME/lib/aspectjrt.jar:$EXTRACTION/junit.jar diff --git a/docs/modules/ROOT/pages/teaching/exercises/setpaths.bat b/docs/modules/ROOT/pages/teaching/exercises/setpaths.bat new file mode 100644 index 000000000..6722060ea --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/setpaths.bat @@ -0,0 +1,15 @@ +@echo off + +rem Change this to be the full path for this directory +set EXTRACTION=c:\aj-oopsla + +if exist "%JAVA_HOME%\bin\java.exe" goto haveJava +if exist "%JAVA_HOME%\bin\java.bat" goto haveJava +if exist "%JAVA_HOME%\bin\java" goto haveJava +echo java does not exist as %JAVA_HOME%\bin\java +echo please fix the JAVA_HOME environment variable + +:haveJava +set ASPECTJ_HOME=%EXTRACTION%\aspectj +set PATH=%ASPECTJ_HOME%\bin;%PATH% +set CLASSPATH=.;%ASPECTJ_HOME%\lib\aspectjrt.jar;%EXTRACTION%\junit.jar diff --git a/docs/modules/ROOT/pages/teaching/exercises/support/Log.java b/docs/modules/ROOT/pages/teaching/exercises/support/Log.java new file mode 100644 index 000000000..7c615836e --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/support/Log.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package support; + +import java.util.List; +import java.util.ArrayList; + +public class Log { + static List data = new ArrayList(); + + public static void write(String s) { + data.add(s); + } + + public static List getData() { + return data; + } + + public static void clear() { + data.clear(); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/CoreTest.java b/docs/modules/ROOT/pages/teaching/exercises/tests/CoreTest.java new file mode 100644 index 000000000..e069e67b5 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/CoreTest.java @@ -0,0 +1,79 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class CoreTest extends TestCase { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test.class); + } + + Box bb; + Point p1; + Point p2; + Line l1; + SlothfulPoint sloth1; + Group g; + + public void setUp() { + p1 = new Point(10, 100); + p2 = new Point(20, 200); + l1 = new Line(p1, p2); + bb = new Box(5, 5, 10, 10); + sloth1 = new SlothfulPoint(0, 0); + g = new Group(p1); + } + + public final void testCreate() { + assertEquals(p1.getX(), 10); + assertEquals(p1.getY(), 100); + + assertEquals(l1.getP1(), p1); + assertEquals(l1.getP2(), p2); + } + + public final void testSetPoint() { + p1.setX(20); + assertEquals(p1.getX(), 20); + assertEquals(p1.getY(), 100); + + p1.setY(10); + assertEquals(p1.getX(), 20); + assertEquals(p1.getY(), 10); + } + + public final void testMoveLine1() { + l1.move(40, 40); + assertEquals(l1.getP1(), p1); + assertEquals(l1.getP2(), p2); + + assertEquals(p1.getX(), 50); + assertEquals(p1.getY(), 140); + + assertEquals(p2.getX(), 60); + assertEquals(p2.getY(), 240); + } + + public final void testMoveLine2() { + l1.move(-10, -10); + assertEquals(p1.getX(), 0); + assertEquals(p1.getY(), 90); + + assertEquals(p2.getX(), 10); + assertEquals(p2.getY(), 190); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test2a.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2a.java new file mode 100644 index 000000000..8035a0543 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2a.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2a extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2a.class); + } + + public void testTooSmall() { + Point p1 = new Point(10, 100); + try { + p1.setX(-10); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } + + public void testNotTooSmall() { + Point p1 = new Point(10, 100); + p1.setX(0); + } + + public void testMove() { + Line l1 = new Line(new Point(10, 100), new Point(20, 200)); + try { + l1.move(-500, -500); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test2b.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2b.java new file mode 100644 index 000000000..2e2fecf73 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2b.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2b extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2b.class); + } + + public void testNull() { + Point p1 = new Point(10, 100); + Group g = new Group(p1); + + try { + g.add(null); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } + + public void testNonNull() { + Point p1 = new Point(10, 100); + Group g = new Group(p1); + Point p2 = new Point(20, 200); + + g.add(p2); + } + +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test2c.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2c.java new file mode 100644 index 000000000..2bb7093ee --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2c.java @@ -0,0 +1,43 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2c extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2c.class); + } + + public void testSelf() { + Point p1 = new Point(10, 100); + Group g = new Group(p1); + + try { + g.add(g); + fail("should have thrown IllegalArgumentException"); + } catch (IllegalArgumentException ea) { + } + } + + public void testNotSelf() { + Point p1 = new Point(10, 100); + Group g1 = new Group(p1); + Group g2 = new Group(p1); + + g1.add(g2); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test2d.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2d.java new file mode 100644 index 000000000..baabd9aea --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2d.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2d extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2d.class); + } + + public void testOutOfBounds() { + Point p1 = new Point(10, 100); + + p1.setX(-10); + p1.setY(-100); + + assertEquals(0, p1.getX()); + assertEquals(0, p1.getY()); + } + + public void testInBounds() { + Point p1 = new Point(10, 100); + + p1.setX(30); + p1.setY(300); + + assertEquals(30, p1.getX()); + assertEquals(300, p1.getY()); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test2e.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2e.java new file mode 100644 index 000000000..bf388cbb6 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2e.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2e extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2e.class); + } + + public void testNonMoving() { + Point sp = new Point(10, 10) { public void move(int x, int y) {} }; + try { + sp.move(10, 10); + fail("should have thrown IllegalStateException"); + } catch (IllegalStateException e) { } + } + + public void testMoving() { + Point p1 = new Point(10, 100); + p1.move(3, 30); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test2f.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2f.java new file mode 100644 index 000000000..adcf58923 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test2f.java @@ -0,0 +1,40 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; + +import junit.framework.*; + +public class Test2f extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test2f.class); + } + + public void testSloth() { + FigureElement fe = new SlothfulPoint(10, 10); + try { + fe.move(10, 10); + fail("should have thrown IllegalStateException"); + } catch (IllegalStateException e) { } + } + + public void testNonSloth() { + Point p1 = new Point(10, 100); + Point p2 = new Point(20, 200); + Line l1 = new Line(p1, p2); + + l1.move(3, 30); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test3a.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3a.java new file mode 100644 index 000000000..8baf39096 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3a.java @@ -0,0 +1,59 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; +import junit.framework.*; +import java.util.List; +import java.util.Arrays; + +public class Test3a extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3a.class); + } + + public void testMovePointLog() { + Point p1 = new Point(10, 100); + + Log.clear(); + p1.move(20, 30); + List foundLog = Log.getData(); + + List desiredLog = + Arrays.asList(new String[] { + "execution(void figures.Point.move(int, int))" + }); + + assertEquals(desiredLog, foundLog); + } + + public void testMoveLineLog() { + Point p1 = new Point(10, 100); + Point p2 = new Point(20, 200); + Line l = new Line(p1, p2); + + Log.clear(); + l.move(20, 30); + List foundLog = Log.getData(); + + List desiredLog = + Arrays.asList(new String[] { + "execution(void figures.Line.move(int, int))", + "execution(void figures.Point.move(int, int))", + "execution(void figures.Point.move(int, int))" + }); + assertEquals(desiredLog, foundLog); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test3b.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3b.java new file mode 100644 index 000000000..294951824 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3b.java @@ -0,0 +1,59 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; +import junit.framework.*; +import java.util.List; +import java.util.Arrays; + +public class Test3b extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3b.class); + } + + public void testMovePointLog() { + Point p1 = new Point(10, 100); + + Log.clear(); + p1.move(20, 30); + List foundLog = Log.getData(); + + List desiredLog = + Arrays.asList(new String[] { + "execution(void figures.Point.move(int, int)) at Point(10, 100)" + }); + + assertEquals(desiredLog, foundLog); + } + + public void testMoveLineLog() { + Point p1 = new Point(10, 100); + Point p2 = new Point(20, 200); + Line l = new Line(p1, p2); + + Log.clear(); + l.move(20, 30); + List foundLog = Log.getData(); + + List desiredLog = + Arrays.asList(new String[] { + "execution(void figures.Line.move(int, int)) at Line(Point(10, 100), Point(20, 200))", + "execution(void figures.Point.move(int, int)) at Point(10, 100)", + "execution(void figures.Point.move(int, int)) at Point(20, 200)" + }); + assertEquals(desiredLog, foundLog); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test3c.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3c.java new file mode 100644 index 000000000..d563d8056 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3c.java @@ -0,0 +1,52 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; +import junit.framework.*; +import java.util.List; +import java.util.Arrays; + +public class Test3c extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3c.class); + } + + public void testCreateWithPointLog() { + Log.clear(); + Point p1 = new Point(10, 100); + Group g = new Group(p1); + List foundLog = Log.getData(); + + List desiredLog = + Arrays.asList(new String[] { + "adding Point" + }); + assertEquals(desiredLog, foundLog); + } + + public void testCreateWithoutPointLog() { + Log.clear(); + Point p1 = new Point(10, 100); + Point p2 = new Point(20, 200); + Line l = new Line(p1, p2); + Group g = new Group(l); + List foundLog = Log.getData(); + + List desiredLog = Arrays.asList(new String[] {}); + assertEquals(desiredLog, foundLog); + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test3d.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3d.java new file mode 100644 index 000000000..0dc4c0ad4 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3d.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; +import junit.framework.*; +import java.util.List; +import java.util.Arrays; + +public class Test3d extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3d.class); + } + + public void testDuplicateAdd() { + Log.clear(); + Point p1 = new Point(10, 100); + Group g1 = new Group(p1); + try { + Group g2 = new Group(p1); + fail("should have thrown IllegalStateException"); + } catch (IllegalStateException ea) { + } + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test3e.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3e.java new file mode 100644 index 000000000..c223a83cd --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test3e.java @@ -0,0 +1,39 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import support.Log; +import junit.framework.*; +import java.util.List; +import java.util.Arrays; + +public class Test3e extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test3e.class); + } + + public void testDuplicateAdd() { + Log.clear(); + Point p1 = new Point(10, 100); + Group g1 = new Group(p1); + try { + Group g2 = new Group(p1); + fail("should have thrown IllegalStateException"); + } catch (IllegalStateException ea) { + assertEquals(g1.toString(), ea.getMessage()); + } + } +} + diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test4a.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4a.java new file mode 100644 index 000000000..4087f39a6 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4a.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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4a extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4a.class); + } + + public void testGroupBounds() { + assertEquals(g.getBounds(), FigureElement.MAX_BOUNDS); + } +} diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test4b.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4b.java new file mode 100644 index 000000000..3429b3d24 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4b.java @@ -0,0 +1,61 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4b extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4b.class); + } + + 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_BOUNDS.getWidth()); + assertTrue("bounds for this group should not be the whole canvas", + g.getBounds().getHeight() < FigureElement.MAX_BOUNDS.getHeight()); + } +} + + diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test4c.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4c.java new file mode 100644 index 000000000..544409db1 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4c.java @@ -0,0 +1,78 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4c extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4c.class); + } + + public void testBasicEquality() { + assertTrue(g.getBounds() == g.getBounds()); + } + + public void testEqualityAfterAddition() { + Point p0 = new Point(1, 2); + Point p1 = new Point(2, 3); + + Group g0 = new Group(p0); + Group g1 = new Group(p1); + + Rectangle r0 = g0.getBounds(); + Rectangle r1 = g1.getBounds(); + assertTrue(r0 != r1); + g0.add(new Point(37, 90)); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + + g1.add(new Point(4, 8)); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + } + + public void testEqualityAfterMove() { + Point p0 = new Point(1, 2); + Point p1 = new Point(2, 3); + + Group g0 = new Group(p0); + Group g1 = new Group(p1); + + Rectangle r0 = g0.getBounds(); + Rectangle r1 = g1.getBounds(); + assertTrue(r0 != r1); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + + g0.move(3, 1); + Rectangle r00 = g0.getBounds(); + Rectangle r10 = g1.getBounds(); + + assertTrue(r10 != r00); + assertTrue(r0 != r00); + assertTrue(g0.getBounds() == r00); + } +} + + diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test4d.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4d.java new file mode 100644 index 000000000..dc7770f34 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4d.java @@ -0,0 +1,75 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4d extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4d.class); + } + + public void testBasicEquality() { + assertTrue(g.getBounds() == g.getBounds()); + } + + public void testNonGroupMove() { + p1.move(3, 27); + } + + public void testEqualityAfterAddition() { + Rectangle r = g.getBounds(); + g.add(new Point(37, 90)); + assertTrue(g.getBounds() == r); + } + + public void testEqualityAfterMove() { + Point p0 = new Point(1, 2); + Point p1 = new Point(2, 3); + + Group g0 = new Group(p0); + Group g1 = new Group(p1); + + Rectangle r0 = g0.getBounds(); + Rectangle r1 = g1.getBounds(); + assertTrue(r0 != r1); + assertTrue(g0.getBounds() == r0); + assertTrue(g1.getBounds() != r0); + assertTrue(g0.getBounds() != r1); + assertTrue(g1.getBounds() == r1); + + p0.move(3, 1); + Rectangle r00 = g0.getBounds(); + Rectangle r10 = g1.getBounds(); + + assertTrue(r10 != r00); + assertTrue(r0 != r00); + assertTrue(g0.getBounds() == r00); + } + + public void testEqualityAfterMove0() { + g = new Group(p1); + Rectangle r0 = g.getBounds(); + assertTrue(g.getBounds() == r0); + p1.move(3, 1); + Rectangle r1 = g.getBounds(); + assertTrue(r0 != r1); + assertTrue(r1 == g.getBounds()); + } +} + + diff --git a/docs/modules/ROOT/pages/teaching/exercises/tests/Test4e.java b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4e.java new file mode 100644 index 000000000..4d8b18466 --- /dev/null +++ b/docs/modules/ROOT/pages/teaching/exercises/tests/Test4e.java @@ -0,0 +1,62 @@ +/* ******************************************************************* + * 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 Eclipse Public License v 2.0 + * which accompanies this distribution and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package tests; + +import figures.*; +import java.awt.Rectangle; + +import junit.framework.*; + +public class Test4e extends CoreTest { + + public static void main(String[] args) { + junit.textui.TestRunner.run(Test4e.class); + } + + 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()); + } +} + + |