finally totally and completely stomped out "introduction" minor formatting changes generating better filenames for the progguide added A4 version of quick referencetags/V1_1_0_RC2
<arg value="${xml-source-dir}/${xml-source-root}"/> | <arg value="${xml-source-dir}/${xml-source-root}"/> | ||||
<arg value="${xsl-source-file}"/> | <arg value="${xsl-source-file}"/> | ||||
<arg value="base.dir=${xml-target-dir}/"/> | <arg value="base.dir=${xml-target-dir}/"/> | ||||
<arg value="use.id.as.filename=1"/> | |||||
</java> | </java> | ||||
</target> | </target> | ||||
<authorgroup> | <authorgroup> | ||||
<author> | <author> | ||||
<othername>the AspectJ Team</othername> | |||||
<othername>the AspectJ Team</othername> | |||||
</author> | </author> | ||||
</authorgroup> | </authorgroup> | ||||
<legalnotice> | <legalnotice> | ||||
<para>Copyright (c) 1998-2001 Xerox Corporation, | |||||
<para>Copyright (c) 1998-2001 Xerox Corporation, | |||||
2002 Palo Alto Research Center, Incorporated, | 2002 Palo Alto Research Center, Incorporated, | ||||
2003 Contributors. | 2003 Contributors. | ||||
All rights reserved. | All rights reserved. | ||||
<abstract> | <abstract> | ||||
<para> | <para> | ||||
This guide describes the tools in the AspectJ 1.1 development environment. | |||||
See also | |||||
<ulink url="../progguide/index.html">The AspectJ Programming Guide</ulink>, | |||||
the documentation for the AspectJ | |||||
<ulink url="../ant-tasks.html">Ant tasks</ulink>, | |||||
and the documentation available with the AspectJ support available for | |||||
various integrated development environments | |||||
(e.g., Eclipse, Emacs, JBuilder, and NetBeans). | |||||
This guide describes the tools in the AspectJ 1.1 development | |||||
environment. See also <ulink url="../progguide/index.html">The | |||||
AspectJ Programming Guide</ulink>, the documentation for the | |||||
AspectJ <ulink url="../ant-tasks.html">Ant tasks</ulink>, and the | |||||
documentation available with the AspectJ support available for | |||||
various integrated development environments (e.g., Eclipse, Emacs, | |||||
JBuilder, and NetBeans). | |||||
</para> | </para> | ||||
</abstract> | </abstract> | ||||
</bookinfo> | </bookinfo> |
* warranty about the software, its performance or its conformity to any | * warranty about the software, its performance or its conformity to any | ||||
* specification. | * specification. | ||||
*/ | */ | ||||
package bean; | package bean; | ||||
import java.beans.*; | import java.beans.*; | ||||
import java.io.Serializable; | import java.io.Serializable; | ||||
/* | /* | ||||
* Add bound properties and serialization to point objects | |||||
* Add bound properties and serialization to point objects | |||||
*/ | */ | ||||
aspect BoundPoint { | aspect BoundPoint { | ||||
/* | /* | ||||
* privately introduce a field into Point to hold the property | * privately introduce a field into Point to hold the property | ||||
* change support object. `this' is a reference to a Point object. | |||||
* change support object. `this' is a reference to a Point object. | |||||
*/ | */ | ||||
private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); | private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); | ||||
support.addPropertyChangeListener(listener); | support.addPropertyChangeListener(listener); | ||||
} | } | ||||
public void Point.addPropertyChangeListener(String propertyName, | |||||
public void Point.addPropertyChangeListener(String propertyName, | |||||
PropertyChangeListener listener){ | PropertyChangeListener listener){ | ||||
support.addPropertyChangeListener(propertyName, listener); | support.addPropertyChangeListener(propertyName, listener); | ||||
} | } | ||||
public void Point.removePropertyChangeListener(String propertyName, | |||||
public void Point.removePropertyChangeListener(String propertyName, | |||||
PropertyChangeListener listener) { | PropertyChangeListener listener) { | ||||
support.removePropertyChangeListener(propertyName, listener); | support.removePropertyChangeListener(propertyName, listener); | ||||
} | } | ||||
/** | /** | ||||
* Advice to get the property change event fired when the | * Advice to get the property change event fired when the | ||||
* setters are called. It's around advice because you need | |||||
* setters are called. It's around advice because you need | |||||
* the old value of the property. | * the old value of the property. | ||||
*/ | */ | ||||
void around(Point p): setter(p) { | void around(Point p): setter(p) { | ||||
String propertyName = | |||||
String propertyName = | |||||
thisJoinPointStaticPart.getSignature().getName().substring("set".length()); | thisJoinPointStaticPart.getSignature().getName().substring("set".length()); | ||||
int oldX = p.getX(); | |||||
int oldY = p.getY(); | |||||
proceed(p); | |||||
if (propertyName.equals("X")){ | |||||
int oldX = p.getX(); | |||||
int oldY = p.getY(); | |||||
proceed(p); | |||||
if (propertyName.equals("X")){ | |||||
firePropertyChange(p, propertyName, oldX, p.getX()); | firePropertyChange(p, propertyName, oldX, p.getX()); | ||||
} else { | |||||
} else { | |||||
firePropertyChange(p, propertyName, oldY, p.getY()); | firePropertyChange(p, propertyName, oldY, p.getY()); | ||||
} | |||||
} | |||||
} | } | ||||
/* | /* | ||||
* Utility to fire the property change event. | * Utility to fire the property change event. | ||||
*/ | */ | ||||
void firePropertyChange(Point p, | |||||
String property, | |||||
double oldval, | |||||
void firePropertyChange(Point p, | |||||
String property, | |||||
double oldval, | |||||
double newval) { | double newval) { | ||||
p.support.firePropertyChange(property, | |||||
new Double(oldval), | |||||
p.support.firePropertyChange(property, | |||||
new Double(oldval), | |||||
new Double(newval)); | new Double(newval)); | ||||
} | } | ||||
} | } |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
upon this software are permitted. Any distribution of this software or | upon this software are permitted. Any distribution of this software or | ||||
derivative works must comply with all applicable United States export control | derivative works must comply with all applicable United States export control | ||||
laws. | laws. | ||||
*/ | */ | ||||
package bean; | package bean; | ||||
import java.beans.*; | import java.beans.*; | ||||
* this method reports that a propery has changed | * this method reports that a propery has changed | ||||
*/ | */ | ||||
public void propertyChange(PropertyChangeEvent e){ | public void propertyChange(PropertyChangeEvent e){ | ||||
System.out.println("Property " + e.getPropertyName() + " changed from " + | |||||
e.getOldValue() + " to " + e.getNewValue() ); | |||||
System.out.println("Property " + e.getPropertyName() + " changed from " + | |||||
e.getOldValue() + " to " + e.getNewValue() ); | |||||
} | } | ||||
/** | /** | ||||
* main: test the program | * main: test the program | ||||
*/ | */ | ||||
public static void main(String[] args){ | public static void main(String[] args){ | ||||
Point p1 = new Point(); | |||||
p1.addPropertyChangeListener(new Demo()); | |||||
System.out.println("p1 =" + p1); | |||||
p1.setRectangular(5,2); | |||||
System.out.println("p1 =" + p1); | |||||
p1.setX( 6 ); | |||||
p1.setY( 3 ); | |||||
System.out.println("p1 =" + p1); | |||||
p1.offset(6,4); | |||||
System.out.println("p1 =" + p1); | |||||
save(p1, fileName); | |||||
Point p2 = (Point) restore(fileName); | |||||
System.out.println("Had: " + p1); | |||||
System.out.println("Got: " + p2); | |||||
Point p1 = new Point(); | |||||
p1.addPropertyChangeListener(new Demo()); | |||||
System.out.println("p1 =" + p1); | |||||
p1.setRectangular(5,2); | |||||
System.out.println("p1 =" + p1); | |||||
p1.setX( 6 ); | |||||
p1.setY( 3 ); | |||||
System.out.println("p1 =" + p1); | |||||
p1.offset(6,4); | |||||
System.out.println("p1 =" + p1); | |||||
save(p1, fileName); | |||||
Point p2 = (Point) restore(fileName); | |||||
System.out.println("Had: " + p1); | |||||
System.out.println("Got: " + p2); | |||||
} | } | ||||
/** | /** | ||||
* Save a serializable object to a file | * Save a serializable object to a file | ||||
*/ | */ | ||||
static void save(Serializable p, String fn){ | static void save(Serializable p, String fn){ | ||||
try { | |||||
System.out.println("Writing to file: " + p); | |||||
FileOutputStream fo = new FileOutputStream(fn); | |||||
ObjectOutputStream so = new ObjectOutputStream(fo); | |||||
so.writeObject(p); | |||||
so.flush(); | |||||
} catch (Exception e) { | |||||
System.out.println(e); | |||||
System.exit(1); | |||||
} | |||||
try { | |||||
System.out.println("Writing to file: " + p); | |||||
FileOutputStream fo = new FileOutputStream(fn); | |||||
ObjectOutputStream so = new ObjectOutputStream(fo); | |||||
so.writeObject(p); | |||||
so.flush(); | |||||
} catch (Exception e) { | |||||
System.out.println(e); | |||||
System.exit(1); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Restore a serializable object from the file | * Restore a serializable object from the file | ||||
*/ | */ | ||||
static Object restore(String fn){ | static Object restore(String fn){ | ||||
try { | |||||
Object result; | |||||
System.out.println("Reading from file: " + fn); | |||||
FileInputStream fi = new FileInputStream(fn); | |||||
ObjectInputStream si = new ObjectInputStream(fi); | |||||
return si.readObject(); | |||||
} catch (Exception e) { | |||||
System.out.println(e); | |||||
System.exit(1); | |||||
} | |||||
return null; | |||||
try { | |||||
Object result; | |||||
System.out.println("Reading from file: " + fn); | |||||
FileInputStream fi = new FileInputStream(fn); | |||||
ObjectInputStream si = new ObjectInputStream(fi); | |||||
return si.readObject(); | |||||
} catch (Exception e) { | |||||
System.out.println(e); | |||||
System.exit(1); | |||||
} | |||||
return null; | |||||
} | } | ||||
} | } |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
*/ | */ | ||||
package bean; | package bean; | ||||
* Return the X coordinate | * Return the X coordinate | ||||
*/ | */ | ||||
public int getX(){ | public int getX(){ | ||||
return x; | |||||
return x; | |||||
} | } | ||||
/** | /** | ||||
* Return the y coordinate | * Return the y coordinate | ||||
*/ | */ | ||||
public int getY(){ | public int getY(){ | ||||
return y; | |||||
return y; | |||||
} | } | ||||
/** | /** | ||||
* Set the x and y coordinates | * Set the x and y coordinates | ||||
*/ | */ | ||||
public void setRectangular(int newX, int newY){ | public void setRectangular(int newX, int newY){ | ||||
setX(newX); | |||||
setY(newY); | |||||
setX(newX); | |||||
setY(newY); | |||||
} | } | ||||
/** | /** | ||||
* Set the X coordinate | * Set the X coordinate | ||||
*/ | */ | ||||
public void setX(int newX) { | public void setX(int newX) { | ||||
x = newX; | |||||
x = newX; | |||||
} | } | ||||
/** | /** | ||||
* set the y coordinate | * set the y coordinate | ||||
*/ | */ | ||||
public void setY(int newY) { | public void setY(int newY) { | ||||
y = newY; | |||||
y = newY; | |||||
} | } | ||||
/** | /** | ||||
* Move the point by the specified x and y offset | * Move the point by the specified x and y offset | ||||
*/ | */ | ||||
public void offset(int deltaX, int deltaY){ | public void offset(int deltaX, int deltaY){ | ||||
setRectangular(x + deltaX, y + deltaY); | |||||
setRectangular(x + deltaX, y + deltaY); | |||||
} | } | ||||
/** | /** | ||||
* MAke a string of this | |||||
* Make a string of this | |||||
*/ | */ | ||||
public String toString(){ | public String toString(){ | ||||
return "(" + getX() + ", " + getY() + ")" ; | |||||
return "(" + getX() + ", " + getY() + ")" ; | |||||
} | } | ||||
} | } |
p1.setPolar(Math.PI, 1.0); | p1.setPolar(Math.PI, 1.0); | ||||
try { | try { | ||||
p2 = (Point)p1.clone(); | |||||
p2 = (Point)p1.clone(); | |||||
} catch (CloneNotSupportedException e) {} | } catch (CloneNotSupportedException e) {} | ||||
System.out.println("p1 =" + p1 ); | System.out.println("p1 =" + p1 ); | ||||
System.out.println("p2 =" + p2 ); | System.out.println("p2 =" + p2 ); |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
Button.java | |||||
*/ | */ | ||||
static final String defaultText = "cycle color"; | static final String defaultText = "cycle color"; | ||||
Button(Display display) { | Button(Display display) { | ||||
super(); | |||||
setLabel(defaultText); | |||||
setBackground(defaultBackgroundColor); | |||||
setForeground(defaultForegroundColor); | |||||
addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent e) { | |||||
Button.this.click(); | |||||
} | |||||
}); | |||||
display.addToFrame(this); | |||||
super(); | |||||
setLabel(defaultText); | |||||
setBackground(defaultBackgroundColor); | |||||
setForeground(defaultForegroundColor); | |||||
addActionListener(new ActionListener() { | |||||
public void actionPerformed(ActionEvent e) { | |||||
Button.this.click(); | |||||
} | |||||
}); | |||||
display.addToFrame(this); | |||||
} | } | ||||
public void click() {} | public void click() {} | ||||
} | } |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
ColorLabel.java | |||||
*/ | */ | ||||
package observer; | package observer; | ||||
class ColorLabel extends Label { | class ColorLabel extends Label { | ||||
ColorLabel(Display display) { | ColorLabel(Display display) { | ||||
super(); | |||||
display.addToFrame(this); | |||||
super(); | |||||
display.addToFrame(this); | |||||
} | } | ||||
final static Color[] colors = {Color.red, Color.blue, | final static Color[] colors = {Color.red, Color.blue, | ||||
Color.green, Color.magenta}; | |||||
Color.green, Color.magenta}; | |||||
private int colorIndex = 0; | private int colorIndex = 0; | ||||
private int cycleCount = 0; | private int cycleCount = 0; | ||||
void colorCycle() { | void colorCycle() { | ||||
cycleCount++; | |||||
colorIndex = (colorIndex + 1) % colors.length; | |||||
setBackground(colors[colorIndex]); | |||||
setText("" + cycleCount); | |||||
cycleCount++; | |||||
colorIndex = (colorIndex + 1) % colors.length; | |||||
setBackground(colors[colorIndex]); | |||||
setText("" + cycleCount); | |||||
} | } | ||||
} | } | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
Demo.java | |||||
*/ | */ | ||||
package observer; | package observer; | ||||
public class Demo { | public class Demo { | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
Display display = new Display(); | |||||
Button b1 = new Button(display); | |||||
Button b2 = new Button(display); | |||||
ColorLabel c1 = new ColorLabel(display); | |||||
ColorLabel c2 = new ColorLabel(display); | |||||
ColorLabel c3 = new ColorLabel(display); | |||||
Display display = new Display(); | |||||
Button b1 = new Button(display); | |||||
Button b2 = new Button(display); | |||||
ColorLabel c1 = new ColorLabel(display); | |||||
ColorLabel c2 = new ColorLabel(display); | |||||
ColorLabel c3 = new ColorLabel(display); | |||||
b1.addObserver(c1); | |||||
b1.addObserver(c2); | |||||
b2.addObserver(c3); | |||||
b1.addObserver(c1); | |||||
b1.addObserver(c2); | |||||
b2.addObserver(c3); | |||||
} | } | ||||
} | } | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
Display.java | |||||
*/ | */ | ||||
package observer; | package observer; | ||||
protected Frame frame = new Frame("Subject/Observer Demo"); | protected Frame frame = new Frame("Subject/Observer Demo"); | ||||
Display() { | Display() { | ||||
frame.addWindowListener(new WindowAdapter() { | |||||
public void windowClosing(WindowEvent e) {System.exit(0);} | |||||
}); | |||||
frame.addWindowListener(new WindowAdapter() { | |||||
public void windowClosing(WindowEvent e) {System.exit(0);} | |||||
}); | |||||
frame.add(this, BorderLayout.CENTER); | |||||
frame.pack(); | |||||
frame.setVisible(true); | |||||
frame.add(this, BorderLayout.CENTER); | |||||
frame.pack(); | |||||
frame.setVisible(true); | |||||
} | } | ||||
void addToFrame(Component c) { | void addToFrame(Component c) { | ||||
add(c); | |||||
frame.pack(); | |||||
} | |||||
add(c); | |||||
frame.pack(); | |||||
} | |||||
} | } | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
Observer.java | |||||
*/ | */ | ||||
package observer; | package observer; | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
Subject.java | |||||
*/ | */ | ||||
package observer; | package observer; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
SubjectObserverProtocol.java | |||||
*/ | */ | ||||
package observer; | package observer; | ||||
abstract pointcut stateChanges(Subject s); | abstract pointcut stateChanges(Subject s); | ||||
after(Subject s): stateChanges(s) { | after(Subject s): stateChanges(s) { | ||||
for (int i = 0; i < s.getObservers().size(); i++) { | |||||
((Observer)s.getObservers().elementAt(i)).update(); | |||||
} | |||||
for (int i = 0; i < s.getObservers().size(); i++) { | |||||
((Observer)s.getObservers().elementAt(i)).update(); | |||||
} | |||||
} | } | ||||
private Vector Subject.observers = new Vector(); | private Vector Subject.observers = new Vector(); | ||||
public void Subject.addObserver(Observer obs) { | |||||
observers.addElement(obs); | |||||
obs.setSubject(this); | |||||
public void Subject.addObserver(Observer obs) { | |||||
observers.addElement(obs); | |||||
obs.setSubject(this); | |||||
} | } | ||||
public void Subject.removeObserver(Observer obs) { | |||||
observers.removeElement(obs); | |||||
obs.setSubject(null); | |||||
public void Subject.removeObserver(Observer obs) { | |||||
observers.removeElement(obs); | |||||
obs.setSubject(null); | |||||
} | } | ||||
public Vector Subject.getObservers() { return observers; } | public Vector Subject.getObservers() { return observers; } | ||||
private Subject Observer.subject = null; | private Subject Observer.subject = null; | ||||
public void Observer.setSubject(Subject s) { subject = s; } | public void Observer.setSubject(Subject s) { subject = s; } | ||||
public Subject Observer.getSubject() { return subject; } | public Subject Observer.getSubject() { return subject; } | ||||
} | } | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
SubjectObserverProtocolImpl.java | |||||
*/ | */ | ||||
package observer; | package observer; | ||||
declare parents: ColorLabel implements Observer; | declare parents: ColorLabel implements Observer; | ||||
public void ColorLabel.update() { | public void ColorLabel.update() { | ||||
colorCycle(); | |||||
colorCycle(); | |||||
} | } | ||||
pointcut stateChanges(Subject s): | |||||
target(s) && | |||||
call(void Button.click()); | |||||
pointcut stateChanges(Subject s): | |||||
target(s) && | |||||
call(void Button.click()); | |||||
} | } | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package telecom; | package telecom; | ||||
* it depends only on timing and on the type of the connection. | * it depends only on timing and on the type of the connection. | ||||
*/ | */ | ||||
public aspect Billing { | public aspect Billing { | ||||
// domination required to get advice on endtiming in the right order | |||||
// precedence required to get advice on endtiming in the right order | |||||
declare precedence: Billing, Timing; | declare precedence: Billing, Timing; | ||||
public static final long LOCAL_RATE = 3; | public static final long LOCAL_RATE = 3; | ||||
public static final long LONG_DISTANCE_RATE = 10; | public static final long LONG_DISTANCE_RATE = 10; | ||||
public Customer Connection.payer; | public Customer Connection.payer; | ||||
public Customer getPayer(Connection conn) { return conn.payer; } | public Customer getPayer(Connection conn) { return conn.payer; } | ||||
/** | /** |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package telecom; | package telecom; | ||||
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package telecom; | package telecom; | ||||
/** | /** | ||||
* Every Customer has a total connection time | * Every Customer has a total connection time | ||||
*/ | */ | ||||
public long Customer.totalConnectTime = 0; | public long Customer.totalConnectTime = 0; | ||||
public long getTotalConnectTime(Customer cust) { | |||||
return cust.totalConnectTime; | |||||
public long getTotalConnectTime(Customer cust) { | |||||
return cust.totalConnectTime; | |||||
} | } | ||||
/** | /** | ||||
* Every connection has a timer | * Every connection has a timer | ||||
/** | /** | ||||
* When to stop the timer | * When to stop the timer | ||||
*/ | */ | ||||
pointcut endTiming(Connection c): target(c) && | |||||
pointcut endTiming(Connection c): target(c) && | |||||
call(void Connection.drop()); | call(void Connection.drop()); | ||||
/** | /** |
package tjp; | package tjp; | ||||
public class Demo { | public class Demo { | ||||
static Demo d; | static Demo d; | ||||
public static void main(String[] args){ | public static void main(String[] args){ | ||||
new Demo().go(); | |||||
new Demo().go(); | |||||
} | } | ||||
void go(){ | void go(){ | ||||
d = new Demo(); | |||||
d.foo(1,d); | |||||
System.out.println(d.bar(new Integer(3))); | |||||
d = new Demo(); | |||||
d.foo(1,d); | |||||
System.out.println(d.bar(new Integer(3))); | |||||
} | } | ||||
void foo(int i, Object o){ | void foo(int i, Object o){ | ||||
System.out.println("Demo.foo(" + i + ", " + o + ")\n"); | |||||
System.out.println("Demo.foo(" + i + ", " + o + ")\n"); | |||||
} | } | ||||
String bar (Integer j){ | String bar (Integer j){ | ||||
System.out.println("Demo.bar(" + j + ")\n"); | |||||
return "Demo.bar(" + j + ")"; | |||||
System.out.println("Demo.bar(" + j + ")\n"); | |||||
return "Demo.bar(" + j + ")"; | |||||
} | } | ||||
} | } |
/* | |||||
/* | |||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
pointcut demoExecs(): within(Demo) && execution(* *(..)); | pointcut demoExecs(): within(Demo) && execution(* *(..)); | ||||
Object around(): demoExecs() && !execution(* go()) && goCut() { | Object around(): demoExecs() && !execution(* go()) && goCut() { | ||||
println("Intercepted message: " + | |||||
thisJoinPointStaticPart.getSignature().getName()); | |||||
println("in class: " + | |||||
thisJoinPointStaticPart.getSignature().getDeclaringType().getName()); | |||||
println("Intercepted message: " + | |||||
thisJoinPointStaticPart.getSignature().getName()); | |||||
println("in class: " + | |||||
thisJoinPointStaticPart.getSignature().getDeclaringType().getName()); | |||||
printParameters(thisJoinPoint); | printParameters(thisJoinPoint); | ||||
println("Running original method: \n" ); | println("Running original method: \n" ); | ||||
Object result = proceed(); | Object result = proceed(); | ||||
String[] names = ((CodeSignature)jp.getSignature()).getParameterNames(); | String[] names = ((CodeSignature)jp.getSignature()).getParameterNames(); | ||||
Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes(); | Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes(); | ||||
for (int i = 0; i < args.length; i++) { | for (int i = 0; i < args.length; i++) { | ||||
println(" " + i + ". " + names[i] + | |||||
" : " + types[i].getName() + | |||||
" = " + args[i]); | |||||
println(" " + i + ". " + names[i] + | |||||
" : " + types[i].getName() + | |||||
" = " + args[i]); | |||||
} | } | ||||
} | } | ||||
} | } |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package tracing; | package tracing; | ||||
/** | /** | ||||
* | |||||
* TwoDShape is an abstract class that defines generic functionality | |||||
* TwoDShape is an abstract class that defines generic functionality | |||||
* for 2D shapes. | * for 2D shapes. | ||||
* | |||||
*/ | */ | ||||
public abstract class TwoDShape { | public abstract class TwoDShape { | ||||
/** | /** |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package tracing.version1; | package tracing.version1; | ||||
/** | /** | ||||
* There are 3 trace levels (values of TRACELEVEL): | * There are 3 trace levels (values of TRACELEVEL): | ||||
* 0 - No messages are printed | * 0 - No messages are printed | ||||
* 1 - Trace messages are printed, but there is no indentation | |||||
* 1 - Trace messages are printed, but there is no indentation | |||||
* according to the call stack | * according to the call stack | ||||
* 2 - Trace messages are printed, and they are indented | * 2 - Trace messages are printed, and they are indented | ||||
* according to the call stack | * according to the call stack |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package tracing.version1; | package tracing.version1; | ||||
/** | /** | ||||
* | * | ||||
* This class connects the tracing functions in the Trace class with | |||||
* This class connects the tracing functions in the Trace class with | |||||
* the constructors and methods in the application classes. | * the constructors and methods in the application classes. | ||||
* | * | ||||
*/ | */ |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package tracing.version2; | package tracing.version2; | ||||
* This class provides support for printing trace messages into a stream. | * This class provides support for printing trace messages into a stream. | ||||
* Trace messages are printed before and after constructors and methods | * Trace messages are printed before and after constructors and methods | ||||
* are executed. | * are executed. | ||||
* It defines one abstract crosscut for injecting that tracing functionality | |||||
* It defines one abstract crosscut for injecting that tracing functionality | |||||
* into any application classes. | * into any application classes. | ||||
* To use it, provide a subclass that concretizes the abstract crosscut. | * To use it, provide a subclass that concretizes the abstract crosscut. | ||||
*/ | */ | ||||
/** | /** | ||||
* There are 3 trace levels (values of TRACELEVEL): | * There are 3 trace levels (values of TRACELEVEL): | ||||
* 0 - No messages are printed | * 0 - No messages are printed | ||||
* 1 - Trace messages are printed, but there is no indentation | |||||
* 1 - Trace messages are printed, but there is no indentation | |||||
* according to the call stack | * according to the call stack | ||||
* 2 - Trace messages are printed, and they are indented | * 2 - Trace messages are printed, and they are indented | ||||
* according to the call stack | * according to the call stack |
/* | /* | ||||
Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | Copyright (c) Xerox Corporation 1998-2002. All rights reserved. | ||||
Use and copying of this software and preparation of derivative works based | Use and copying of this software and preparation of derivative works based | ||||
This software is made available AS IS, and Xerox Corporation makes no warranty | This software is made available AS IS, and Xerox Corporation makes no warranty | ||||
about the software, its performance or its conformity to any specification. | about the software, its performance or its conformity to any specification. | ||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
|<--- this code is formatted to fit into 80 columns --->| | |||||
*/ | */ | ||||
package tracing.version2; | package tracing.version2; | ||||
/** | /** | ||||
* | * | ||||
* This class concretizes the abstract crosscut in Trace, | |||||
* This class concretizes the abstract crosscut in Trace, | |||||
* applying the trace facility to these application classes. | * applying the trace facility to these application classes. | ||||
* | * | ||||
*/ | */ |
<chapter id="idioms" xreflabel="Idioms"> | <chapter id="idioms" xreflabel="Idioms"> | ||||
<title>Idioms</title> | <title>Idioms</title> | ||||
<sect1><!-- About this Chapter --> | |||||
<title>About this Chapter</title> | |||||
<sect1 id="idioms-intro"> | |||||
<title>Introduction</title> | |||||
<para>This chapter consists of very short snippets of AspectJ code, | |||||
typically pointcuts, that are particularly evocative or useful. | |||||
This section is a work in progress. | |||||
<para> | |||||
This chapter consists of very short snippets of AspectJ code, | |||||
typically pointcuts, that are particularly evocative or useful. | |||||
This section is a work in progress. | |||||
</para> | </para> | ||||
<para> Here's an example of how to enfore a rule that code in the java.sql | |||||
package can only be used from one particular package in your system. This | |||||
doesn't require any access to code in the java.sql package. | |||||
<para> | |||||
Here's an example of how to enfore a rule that code in the | |||||
java.sql package can only be used from one particular package in | |||||
your system. This doesn't require any access to code in the | |||||
java.sql package. | |||||
</para> | </para> | ||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
pointcut restrictedCall(): | pointcut restrictedCall(): | ||||
call(* java.sql.*.*(..)) || call(java.sql.*.new(..)); | call(* java.sql.*.*(..)) || call(java.sql.*.new(..)); | ||||
/* Any code in my system not in the sqlAccess package */ | |||||
/* Any code in my system not in the sqlAccess package */ | |||||
pointcut illegalSource(): | pointcut illegalSource(): | ||||
within(com.foo..*) && !within(com.foo.sqlAccess.*); | within(com.foo..*) && !within(com.foo.sqlAccess.*); | ||||
not exactly equal to AbstractFacade:</para> | not exactly equal to AbstractFacade:</para> | ||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
pointcut nonAbstract(AbstractFacade af): | |||||
call(* *(..)) | |||||
&& target(af) | |||||
pointcut nonAbstract(AbstractFacade af): | |||||
call(* *(..)) | |||||
&& target(af) | |||||
&& !if(af.getClass() == AbstractFacade.class); | && !if(af.getClass() == AbstractFacade.class); | ||||
]]></programlisting> | ]]></programlisting> | ||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
pointcut nonAbstract(AbstractFacade af): | pointcut nonAbstract(AbstractFacade af): | ||||
call(* *(..)) | |||||
call(* *(..)) | |||||
&& target(af); | && target(af); | ||||
]]></programlisting> | ]]></programlisting> | ||||
</para> | </para> | ||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
pointcut callToUndefinedMethod(): | |||||
call(* AbstractFacade+.*(..)) | |||||
pointcut callToUndefinedMethod(): | |||||
call(* AbstractFacade+.*(..)) | |||||
&& !call(* AbstractFacade.*(..)); | && !call(* AbstractFacade.*(..)); | ||||
]]></programlisting> | ]]></programlisting> | ||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
pointcut executionOfUndefinedMethod(): | pointcut executionOfUndefinedMethod(): | ||||
execution(* *(..)) | |||||
&& within(AbstractFacade+) | |||||
execution(* *(..)) | |||||
&& within(AbstractFacade+) | |||||
&& !within(AbstractFacade) | && !within(AbstractFacade) | ||||
]]></programlisting> | ]]></programlisting> | ||||
<para>To use a per-class variable declared on many classes, | |||||
you can defer initialization until you are in a non-static instance context | |||||
so you can refer to the particular class member. If you want to use | |||||
it from advice (without knowing the particular class at compile-time), | |||||
you can declare a method on the type. | |||||
</para> | |||||
<programlisting><![CDATA[ | |||||
aspect Logging { | |||||
//... | |||||
/** per-Loggable-class reference to per-class Logger */ | |||||
static private Logger Loggable+.staticLogger; | |||||
/** instance getter for static logger (lazy construction) */ | |||||
public Logger Loggable+.getLogger() { // XXX make private to aspect? | |||||
if (null == staticLogger) { | |||||
staticLogger = Logger.getLoggerFor(getClass()); | |||||
} | |||||
return staticLogger; | |||||
} | |||||
/** when logging and logger enabled, log the target and join point */ | |||||
before(Loggable loggable) : target(loggable) && logging() { | |||||
Logger logger = loggable.getLogger(); | |||||
if (logger.enabled()) { | |||||
logger.log(loggable + " at " + thisJoinPoint); | |||||
} | |||||
} | |||||
} | |||||
]]></programlisting> | |||||
</sect1> | </sect1> | ||||
</chapter> | </chapter> |
<title>Implementation Limitations</title> | <title>Implementation Limitations</title> | ||||
<para> | <para> | ||||
Certain elements of AspectJ's semantics are difficult to implement without | |||||
making modifications to the virtual machine. One way to deal with this | |||||
problem would be to specify only the behavior that is easiest to implement. | |||||
We have chosen a somewhat different approach, which is to specify an ideal | |||||
language semantics, as well as a clearly defined way in which | |||||
implementations are allowed to deviate from that semantics. This makes it | |||||
possible to develop conforming AspectJ implementations today, while still | |||||
making it clear what later, and presumably better, implementations should do | |||||
tomorrow. | |||||
The initial implementations of AspectJ have all been | |||||
compiler-based implementations. Certain elements of AspectJ's | |||||
semantics are difficult to implement without making modifications | |||||
to the virtual machine, which a compiler-based implementation | |||||
cannot do. One way to deal with this problem would be to specify | |||||
only the behavior that is easiest to implement. We have chosen a | |||||
somewhat different approach, which is to specify an ideal language | |||||
semantics, as well as a clearly defined way in which | |||||
implementations are allowed to deviate from that semantics. This | |||||
makes it possible to develop conforming AspectJ implementations | |||||
today, while still making it clear what later, and presumably | |||||
better, implementations should do tomorrow. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
</para> | </para> | ||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
before(): get(int Point.x) { System.out.println("got x"); } | |||||
before(): get(int Point.x) { System.out.println("got x"); } | |||||
]]></programlisting> | ]]></programlisting> | ||||
<para> | <para> | ||||
should advise all accesses of a field of type int and name x from instances | |||||
of type (or subtype of) Point. It should do this regardless of whether all | |||||
the source code performing the access was available at the time the aspect | |||||
containing this advice was compiled, whether changes were made later, etc. | |||||
should advise all accesses of a field of type int and name x from | |||||
instances of type (or subtype of) Point. It should do this | |||||
regardless of whether all the source code performing the access | |||||
was available at the time the aspect containing this advice was | |||||
compiled, whether changes were made later, etc. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
But AspectJ implementations are permitted to deviate from this in a | |||||
well-defined way -- they are permitted to advise only accesses in | |||||
<emphasis>code the implementation controls</emphasis>. Each implementation | |||||
is free within certain bounds to provide its own definition of what it means | |||||
to control code. | |||||
But AspectJ implementations are permitted to deviate from this in | |||||
a well-defined way -- they are permitted to advise only accesses | |||||
in <emphasis>code the implementation controls</emphasis>. Each | |||||
implementation is free within certain bounds to provide its own | |||||
definition of what it means to control code. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
In the current AspectJ compiler, ajc, control of the code means having | |||||
source code for any aspects and all the code they should affect available | |||||
during the compile. This means that if some class Client contains code with | |||||
the expression <literal>new Point().x</literal> (which results in a field | |||||
get join point at runtime), the current AspectJ compiler will fail to advise | |||||
that access unless Client.java is compiled at the same the aspect is | |||||
compiled. It also means that join points associated with code in precompiled | |||||
libraries (such as java.lang), and join points associated with code in | |||||
native methods (including their execution join points), can not be advised. | |||||
In the current AspectJ compiler, ajc, control of the code means | |||||
having bytecode for any aspects and all the code they should | |||||
affect available during the compile. This means that if some class | |||||
Client contains code with the expression <literal>new | |||||
Point().x</literal> (which results in a field get join point at | |||||
runtime), the current AspectJ compiler will fail to advise that | |||||
access unless Client.java or Client.class is compiled as well. It | |||||
also means that join points associated with code in native methods | |||||
(including their execution join points) cannot be advised. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
Different join points have different requirements. Method call join points | |||||
can be advised only if ajc controls <emphasis>either</emphasis> the code for | |||||
the caller or the code for the receiver, and some call pointcut designators | |||||
may require caller context (what the static type of the receiver is, for | |||||
example) to pick out join points. Constructor call join points can be | |||||
advised only if ajc controls the code for the caller. Field reference or | |||||
assignment join points can be advised only if ajc controls the code for the | |||||
"caller", the code actually making the reference or assignment. | |||||
Initialization join points can be advised only if ajc controls the code of | |||||
the type being initialized, and execution join points can be advised only if | |||||
ajc controls the code for the method or constructor body in question. | |||||
Different join points have different requirements. Method and | |||||
constructor call join points can be advised only if ajc controls | |||||
the bytecode for the caller. Field reference or assignment join | |||||
points can be advised only if ajc controls the bytecode for the | |||||
"caller", the code actually making the reference or assignment. | |||||
Initialization join points can be advised only if ajc controls the | |||||
bytecode of the type being initialized, and execution join points | |||||
can be advised only if ajc controls the bytecode for the method or | |||||
constructor body in question. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
Aspects that are defined <literal>perthis</literal> or | |||||
<literal>pertarget</literal> also have restrictions based on control of the | |||||
code. In particular, at a join point where the source code for the | |||||
currently executing object is not available, an aspect defined | |||||
<literal>perthis</literal> of that join point will not be associated. So | |||||
aspects defined <literal>perthis(Object)</literal> will not create aspect | |||||
instances for every object, just those whose class the compiler controls. | |||||
Similar restrictions apply to <literal>pertarget</literal> aspects. | |||||
Aspects that are defined <literal>perthis</literal> or | |||||
<literal>pertarget</literal> also have restrictions based on | |||||
control of the code. In particular, at a join point where the | |||||
bytecode for the currently executing object is not available, an | |||||
aspect defined <literal>perthis</literal> of that join point will | |||||
not be associated. So aspects defined | |||||
<literal>perthis(Object)</literal> will not create aspect | |||||
instances for every object unless <literal>Object</literal>is part | |||||
of the compile. Similar restrictions apply to | |||||
<literal>pertarget</literal> aspects. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
Inter-type declarations such as <literal>declare parents</literal> also have | |||||
restrictions based on control of the code. If the code for the target of an | |||||
inter-type declaration is not available, then the inter-type declaration is | |||||
not made on that target. So, <literal>declare parents : String implements | |||||
MyInterface</literal> will not work for | |||||
<literal>java.lang.String</literal>. | |||||
Inter-type declarations such as <literal>declare parents</literal> | |||||
also have restrictions based on control of the code. If the | |||||
bytecode for the target of an inter-type declaration is not | |||||
available, then the inter-type declaration is not made on that | |||||
target. So, <literal>declare parents : String implements | |||||
MyInterface</literal> will not work for | |||||
<literal>java.lang.String</literal> unless | |||||
<literal>java.lang.String</literal> is part of the compile. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
Other AspectJ implementations, indeed, future versions of ajc, may define | |||||
<emphasis>code the implementation controls</emphasis> more liberally. | |||||
Other AspectJ implementations, indeed, future versions of ajc, may | |||||
define <emphasis>code the implementation controls</emphasis> more | |||||
liberally or restrictively. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
Control may mean that classes need only be available in classfile or jarfile | |||||
format. So, even if Client.java and Point.java were precompiled, their join | |||||
points could still be advised. In such a system, though, it might still be | |||||
the case that join points from code of system libraries such as java.lang | |||||
could not be advised. | |||||
</para> | |||||
<para> | |||||
Or control could even include system libraries, thus allowing a call join | |||||
point from java.util.Hashmap to java.lang.Object to be advised. | |||||
</para> | |||||
<para> | |||||
All AspectJ implementations are required to control the code of the | |||||
files that the compiler compiles itself. | |||||
</para> | |||||
<para> | |||||
The important thing to remember is that core concepts of AspectJ, | |||||
such as the join point, are unchanged, regardless of which | |||||
implementation is used. During your development, you will have to | |||||
be aware of the limitations of the ajc compiler you're using, but | |||||
these limitations should not drive the design of your aspects. | |||||
The important thing to remember is that core concepts of AspectJ, | |||||
such as the join point, are unchanged, regardless of which | |||||
implementation is used. During your development, you will have to | |||||
be aware of the limitations of the ajc compiler you're using, but | |||||
these limitations should not drive the design of your aspects. | |||||
</para> | </para> | ||||
</appendix> | </appendix> | ||||
<!-- Local variables: --> | |||||
<!-- fill-column: 79 --> | |||||
<!-- sgml-local-ecat-files: progguide.ced --> | |||||
<!-- sgml-parent-document:("progguide.sgml" "book" "appendix") --> | |||||
<!-- End: --> |
<chapter id="pitfalls" xreflabel="Pitfalls"> | <chapter id="pitfalls" xreflabel="Pitfalls"> | ||||
<title>Pitfalls</title> | <title>Pitfalls</title> | ||||
<sect1><!-- About this Chapter --> | |||||
<title>About this Chapter</title> | |||||
<sect1 id="pitfalls-intro"> | |||||
<title>Introduction</title> | |||||
<para>This chapter consists of aspectj programs that may lead to surprising | |||||
behaviour and how to understand them. | |||||
<para> | |||||
This chapter consists of a few AspectJ programs that may lead to | |||||
surprising behavior and how to understand them. | |||||
</para> | </para> | ||||
</sect1> | </sect1> | ||||
<sect1> | |||||
<sect1 id="pitfalls-infiniteLoops"> | |||||
<title>Infinite loops</title> | <title>Infinite loops</title> | ||||
<para>Here is a Java program with peculiar behavior </para> | |||||
<para> | |||||
Here is a Java program with peculiar behavior | |||||
</para> | |||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
public class Main { | public class Main { | ||||
} | } | ||||
]]></programlisting> | ]]></programlisting> | ||||
<para>This program will never reach the println call, but when it aborts | |||||
will have no stack trace. </para> | |||||
<para> | |||||
This program will never reach the println call, but when it aborts | |||||
may have no stack trace. | |||||
</para> | |||||
<para>This silence is caused by multiple StackOverflowExceptions. First | |||||
the infinite loop in the body of the method generates one, which the | |||||
finally clause tries to handle. But this finally clause also generates an | |||||
infinite loop which the current JVMs can't handle gracefully leading to the | |||||
completely silent abort. </para> | |||||
<para> | |||||
This silence is caused by multiple StackOverflowExceptions. First | |||||
the infinite loop in the body of the method generates one, which the | |||||
finally clause tries to handle. But this finally clause also | |||||
generates an infinite loop which the current JVMs can't handle | |||||
gracefully leading to the completely silent abort. | |||||
</para> | |||||
<para> The following short aspect will also generate this behavior: | |||||
<para> | |||||
The following short aspect will also generate this behavior: | |||||
</para> | </para> | ||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
} | } | ||||
]]></programlisting> | ]]></programlisting> | ||||
<para>Why? Because the call to println is also a call matched by the | |||||
pointcut <literal>call (* *(..))</literal>. We get no output because we | |||||
used simple after() advice. If the aspect were changed to</para> | |||||
<para> | |||||
Why? Because the call to println is also a call matched by the | |||||
pointcut <literal>call (* *(..))</literal>. We get no output because | |||||
we used simple after() advice. If the aspect were changed to | |||||
</para> | |||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
aspect A { | aspect A { | ||||
} | } | ||||
]]></programlisting> | ]]></programlisting> | ||||
<para>Then at least a StackOverflowException with a stack trace would be | |||||
seen. In both cases, though, the overall problem is advice applying within | |||||
its own body. </para> | |||||
<para> | |||||
Then at least a StackOverflowException with a stack trace would be | |||||
seen. In both cases, though, the overall problem is advice applying | |||||
within its own body. | |||||
</para> | |||||
<para>There's a simple idiom to use if you ever have a worry that your | |||||
advice might apply in this way. Just restrict the advice from occurring in | |||||
join points caused within the aspect. So: </para> | |||||
<para> | |||||
There's a simple idiom to use if you ever have a worry that your | |||||
advice might apply in this way. Just restrict the advice from occurring in | |||||
join points caused within the aspect. So: | |||||
</para> | |||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
aspect A { | aspect A { | ||||
} | } | ||||
]]></programlisting> | ]]></programlisting> | ||||
<para>Other solutions might be to more closely restrict the pointcut in | |||||
other ways, for example: </para> | |||||
<para> | |||||
Other solutions might be to more closely restrict the pointcut in | |||||
other ways, for example: | |||||
</para> | |||||
<programlisting><![CDATA[ | <programlisting><![CDATA[ | ||||
aspect A { | aspect A { | ||||
} | } | ||||
]]></programlisting> | ]]></programlisting> | ||||
<para>The moral of the story is that unrestricted generic pointcuts can | |||||
pick out more join points than intended. </para> | |||||
<para> | |||||
The moral of the story is that unrestricted generic pointcuts can | |||||
pick out more join points than intended. | |||||
</para> | |||||
</sect1> | </sect1> | ||||
</chapter> | </chapter> | ||||
<!-- | |||||
Local variables: | |||||
compile-command: "java sax.SAXCount -v progguide.xml && java com.icl.saxon.StyleSheet -w0 progguide.xml progguide.html.xsl" | |||||
fill-column: 79 | |||||
sgml-local-ecat-files: "progguide.ced" | |||||
sgml-parent-document:("progguide.xml" "book" "chapter") | |||||
End: | |||||
--> |
<preface> | |||||
<title>Preface</title> | |||||
<preface id="preface"> | |||||
<title>Preface</title> | |||||
<para> | <para> | ||||
This user's guide does three things. It | |||||
This programming guide does three things. It | |||||
<itemizedlist spacing="compact"> | <itemizedlist spacing="compact"> | ||||
<listitem> | <listitem> | ||||
<para>introduces the AspectJ language</para> | |||||
</listitem> | |||||
<para>introduces the AspectJ language</para> | |||||
</listitem> | |||||
<listitem> | <listitem> | ||||
<para> | |||||
defines each of AspectJ's constructs and their semantics, and</para> | |||||
<para> | |||||
defines each of AspectJ's constructs and their semantics, and | |||||
</para> | |||||
</listitem> | </listitem> | ||||
<listitem> | <listitem> | ||||
<para> | |||||
provides examples of their use.</para> | |||||
<para> | |||||
provides examples of their use. | |||||
</para> | |||||
</listitem> | </listitem> | ||||
</itemizedlist> | </itemizedlist> | ||||
Appendices give a quick reference and a more formal definition of | |||||
AspectJ. | |||||
It includes appendices that give a reference to the syntax of AspectJ, | |||||
a more formal description of AspectJ's semantics, and a description of | |||||
limitations allowed by AspectJ implementations. | |||||
</para> | </para> | ||||
<para>The first section, <xref linkend="gettingstarted" />, provides a gentle | |||||
overview of writing AspectJ programs. It also shows how one can introduce | |||||
AspectJ into an existing development effort in stages, reducing the | |||||
associated risk. You should read this section if this is your first | |||||
exposure to AspectJ and you want to get a sense of what AspectJ is all | |||||
about.</para> | |||||
<para>The second section, <xref linkend="aspectjlanguage" />, covers the | |||||
features of the language in more detail, using code snippets as examples. | |||||
The entire language is covered, and after reading this section, you should | |||||
be able to use all the features of the language correctly.</para> | |||||
<para>The next section, <xref linkend="examples" />, comprises a set of | |||||
complete programs that not only show the features being used, but also try | |||||
to illustrate recommended practice. You should read this section after you | |||||
are familiar with the elements of AspectJ.</para> | |||||
<para>The back matter contains several appendices that cover AspectJ's | |||||
semantics, a quick reference to the language, a glossary of terms and the | |||||
index.</para> | |||||
<para> | |||||
The first section, <xref linkend="starting" />, provides a gentle | |||||
overview of writing AspectJ programs. It also shows how one can | |||||
introduce AspectJ into an existing development effort in stages, | |||||
reducing the associated risk. You should read this section if this is | |||||
your first exposure to AspectJ and you want to get a sense of what | |||||
AspectJ is all about. | |||||
</para> | |||||
</preface> | |||||
<para> | |||||
The second section, <xref linkend="language" />, covers the features of | |||||
the language in more detail, using code snippets as examples. All the | |||||
basics of the language is covered, and after reading this section, you | |||||
should be able to use the language correctly. | |||||
</para> | |||||
<!-- Local variables: --> | |||||
<!-- sgml-local-ecat-files: progguide.ced --> | |||||
<!-- sgml-parent-document:("progguide.sgml" "book" "preface") --> | |||||
<!-- End: --> | |||||
<para> | |||||
The next section, <xref linkend="examples" />, comprises a set of | |||||
complete programs that not only show the features being used, but also | |||||
try to illustrate recommended practice. You should read this section | |||||
after you are familiar with the elements of AspectJ. | |||||
</para> | |||||
<para> | |||||
Finally, there are two short chapters, one on <xref linkend="idioms" /> | |||||
and one on <xref linkend="pitfalls" />. | |||||
</para> | |||||
<para> | |||||
The back matter contains several appendices that cover a <xref | |||||
linkend="quick">quick reference</xref> to the language's syntax, a more | |||||
in depth coverage of its <xref linkend="semantics">semantics</xref>, | |||||
and a description of the latitude enjoyed by its <xref | |||||
linkend="limitations">implementations</xref>. | |||||
</para> | |||||
</preface> |
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" | ||||
"../../lib/docbook/docbook-dtd/docbookx.dtd" | "../../lib/docbook/docbook-dtd/docbookx.dtd" | ||||
[ | [ | ||||
<!ENTITY preface SYSTEM "preface.xml"> | <!ENTITY preface SYSTEM "preface.xml"> | ||||
<!ENTITY gettingstarted SYSTEM "gettingstarted.xml"> | <!ENTITY gettingstarted SYSTEM "gettingstarted.xml"> | ||||
<!ENTITY language SYSTEM "language.xml"> | <!ENTITY language SYSTEM "language.xml"> | ||||
<!ENTITY quickreference SYSTEM "quickreference.xml"> | <!ENTITY quickreference SYSTEM "quickreference.xml"> | ||||
<!ENTITY semantics SYSTEM "semantics.xml"> | <!ENTITY semantics SYSTEM "semantics.xml"> | ||||
<!ENTITY limitations SYSTEM "limitations.xml"> | <!ENTITY limitations SYSTEM "limitations.xml"> | ||||
<!-- <!ENTITY glossary SYSTEM "glossary.xml"> --> | |||||
<!-- <!ENTITY bibliography SYSTEM "bibliography.xml"> --> | |||||
<!ENTITY index SYSTEM "index.xml"> | |||||
<!ENTITY % early "ignore"> | |||||
]> | ]> | ||||
<book> | <book> | ||||
<bookinfo> | <bookinfo> | ||||
<title>The AspectJ<superscript>TM</superscript> Programming Guide</title> | |||||
<title>The AspectJ<superscript>TM</superscript> Programming Guide</title> | |||||
<authorgroup> | <authorgroup> | ||||
<author> | <author> | ||||
<othername>the AspectJ Team</othername> | |||||
<othername>the AspectJ Team</othername> | |||||
</author> | </author> | ||||
</authorgroup> | </authorgroup> | ||||
<legalnotice> | |||||
<para>Copyright (c) 1998-2001 Xerox Corporation, | |||||
2002-2003 Palo Alto Research Center, Incorporated. | |||||
All rights reserved. | |||||
</para> | |||||
</legalnotice> | |||||
<legalnotice> | |||||
<para> | |||||
Copyright (c) 1998-2001 Xerox Corporation, | |||||
2002-2003 Palo Alto Research Center, Incorporated. | |||||
All rights reserved. | |||||
</para> | |||||
</legalnotice> | |||||
<abstract> | <abstract> | ||||
<para> | <para> | ||||
This programming guide describes the AspectJ language. A | |||||
companion guide describes the tools which are part of the | |||||
AspectJ development environment. | |||||
This programming guide describes the AspectJ language. A | |||||
companion guide describes the tools which are part of the | |||||
AspectJ development environment. | |||||
</para> | </para> | ||||
<para> | <para> | ||||
If you are completely new to AspectJ, you should first read | |||||
<xref linkend="gettingstarted"/> for a broad overview of programming | |||||
If you are completely new to AspectJ, you should first read | |||||
<xref linkend="starting"/> for a broad overview of programming | |||||
in AspectJ. If you are already familiar with AspectJ, but want a deeper | in AspectJ. If you are already familiar with AspectJ, but want a deeper | ||||
understanding, you should read <xref linkend="aspectjlanguage"/> and | |||||
understanding, you should read <xref linkend="language"/> and | |||||
look at the examples in the chapter. If you want a more formal | look at the examples in the chapter. If you want a more formal | ||||
definition of AspectJ, you should read <xref linkend="semantics"/>. | definition of AspectJ, you should read <xref linkend="semantics"/>. | ||||
</para> | </para> | ||||
&gettingstarted; | &gettingstarted; | ||||
&language; | &language; | ||||
&examples; | &examples; | ||||
&idioms; | |||||
&idioms; | |||||
&pitfalls; | &pitfalls; | ||||
&quickreference; | &quickreference; | ||||
&semantics; | &semantics; | ||||
&limitations; | &limitations; | ||||
<!-- &glossary; --> | |||||
<!-- &bibliography; --> | |||||
<!-- &index; --> | |||||
</book> | </book> | ||||
<!-- | |||||
Local Variables: | |||||
compile-command: "java com.icl.saxon.StyleSheet -w0 progguide.xml progguide.html.xsl" | |||||
fill-column: 79 | |||||
sgml-indent-step: 3 | |||||
sgml-local-ecat-files: "progguide.ced" | |||||
End: | |||||
--> |