277294.ijbsn.asia<br/>Implement GOF pattern in plain java and aspectj and compare them<br/><br/><a href="http://www.cs.ubc.ca/~jan/AODPs/">http://www.cs.ubc.ca/~jan/AODPs/</a> <br/> <br/>README.txt2008-03-17T17:25:16Z2008-03-17T17:25:16Z<br/>Implementations of GoF Design Patterns in Java and AspectJ<br/>Code base documentation<br/><br/><br/>Overview <br/>========<br/><br/>The goal was to provide parallel implementations in AspectJ and Java that <br/>allow for direct comparisons. It has to be noted that most patterns offer <br/>variability in the implementation approach. We choose the one that appeared <br/>to be the most general. Sometimes, the AspectJ version implements a slightly <br/>different (or additional) case(s). This is because AJ sometimes <br/>allows for additional functionality. Please refer to the web page for a <br/>detailed description of this work.<br/><br/>Example Setup <br/>=============<br/><br/>All pattern examples have a class called Main. This class is the test driver <br/>for the particular example. The Main classes are extensively documented using <br/>ajdoc, usually describing the experimental setup and the assignment of roles <br/>to participants. In most cases, the differences between Java and AspectJ <br/>implementations are also mentioned.<br/><br/>Documentation (ajdoc)<br/>=====================<br/><br/>It is possible to generate the ajdoc documentation for either all examples, <br/>for only the reusable library aspects, or for one particular example. Since <br/>ajdoc shows type names without their package (on the left hand side), multiple <br/>types with the same name (but residing in different packages) may be confused <br/>when the documentation for all examples is generated. <br/>==> Generate documentation for all examples: use the makeDocs batch file. <br/> (1) Change to the directory that you extracted the ZIP archive into. (2) <br/> Type "makeDocs" to generate the HTML documentation in the docs <br/> subdirectory.<br/>==> Generate Documentation for the reusable library aspects: use the provided <br/> makeLibraryDocs batch file. (1) Change to the directory that you extracted <br/> the downloaded ZIP file into. (2) Type "makeLibraryDocs" to generate the <br/> HTML documentation in the docs subdirectory.<br/>==> Generate docs for a single example: use the makeSingleExampleDocs batch <br/> file. (1) Change to the directory that you extracted the downloaded ZIP <br/> file into. (2) Call the batch file. It needs two arguments: the name of <br/> the pattern and the language used. For example, type: <br/> "makeSingleExampleDocs singleton aspectj" or type: <br/> "makeSingleExampleDocs templateMethod java".<br/>Within the ajdoc documentation, we tried to separate type names from our <br/>examples and role names (as presented in GoF). We show roles names in italics <br/>and actual type names in code font. This is reflected in the ajdoc <br/>documentation.<br/><br/>Questions, feedback, suggestions, etc.<br/>The AODP web page is <a href="http://www.cs.ubc.ca/labs/spl/aodp.html">http://www.cs.ubc.ca/labs/spl/aodp.html</a> <br/>Please send all questions, feedback, and suggestions to Jan Hannemann <br/>([email protected]). We are very much interested in improving our code. <br/>Please do not hesitate to drop us a line.<br/><br/><br/>Appendix<br/>========<br/><br/>This appendix outlines how to compile and run the examples provided, and how <br/>to generate ajdoc documentation. A number of DOS batch files exist that <br/>automate these tasks somewhat. Note that they only work in Windows <br/>environments. The following is a list of tasks and a description of what <br/>commands accomplish them. For compiling, running and generating documentation,<br/>two options are given. The first one is using a provided script; the second is <br/>the standard command-line option (longer, but will work on all operation <br/>systems).<br/><br/>Set up your system:<br/>1. Install Java and AspectJ<br/>2. Make sure your CLASSPATH contains the current directory (denoted by a <br/> period), e.g. CLASSPATH=.;C:\...<br/>3. Extract the ZIP file into a directory of your choice <br/>4. Change to that directory<br/><br/>Compile Java and AspectJ versions of a design pattern example (e.g. observer).<br/>Choose one:<br/>� makePattern observer <br/>� ajc @examples\observer\files.lst<br/><br/>Run a compiled example (e.g. observer). Choose one:<br/>� testPattern observer (this runs both Java and AspectJ versions)<br/>� java examples.observer.java.Main (for the Java version), <br/>java examples.observer.java.Main (for the AspectJ version)<br/><br/>Generate documentation for all examples. Choose one:<br/>� makeDocs<br/>� ajdoc -private -d docs @allPatterns.lst<br/><br/>Generate documentation for the library aspects. Choose one:<br/>� makeLibraryDocs<br/>� ajdoc -private -d docs ca.ubc.cs.spl.pattern.library<br/><br/>Generate documentation for a single example (e.g. the AspectJ version of the <br/>observer example). Choose one:<br/>� makeSingleExampleDocs observer aspectj<br/>� ajdoc -private -d docs examples.observer.aspectj<br/><br/>View the generated documentation:<br/>� Open the file index.html (located in the docs/ subdirectory) with your <br/> favorite browser.<br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2008-03-17T17:25:16ZCommand.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package ca.ubc.cs.spl.pattern.library;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.patterns.
*
* Contributor(s):
*/
/**
* This interface is implemented by <i>Command</i> objects.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 05/13/02
*
* @see Button
* @see Label
*/
public interface Command {
/**
* Executes the command.
*
* @param receiver the object this command is manipulating.
*/
public void executeCommand(CommandReceiver receiver);
/**
* Queries the command's executable status. This interface method is
* optional (default: all commands are excutable); a default
* implementation is provided by the abstract CommandProtocol aspect.
*
* @returns a boolean indicating whether the command is excutable.
*/
public boolean isExecutable();
public void execute(); // dummy, aspect calls executeCommand(Receiver) if this method is called
}
</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZCommandInvoker.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package ca.ubc.cs.spl.pattern.library;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.patterns.
*
* Contributor(s):
*/
/**
* This interface is used by extending aspects to say what types
* can be Invokers (i.e. senders of an executeCommand() call).
* This role is assigned by concrete sub-aspects of the <code>CommandProtocol
* </code> pattern aspect.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.1, 10/29/02
*
* @see CommandProtocol
*/
public interface CommandInvoker { } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZCommandProtocol.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package ca.ubc.cs.spl.pattern.library;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.patterns.
*
* Contributor(s):
*/
import java.util.WeakHashMap;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Iterator;
import ca.ubc.cs.spl.pattern.library.Command;
import ca.ubc.cs.spl.pattern.library.CommandInvoker;
import ca.ubc.cs.spl.pattern.library.CommandReceiver;
// TODO: This implementation allows only for exactly one command per invoker.
// That can either stay this way or be replaced with composite (macro)
// commands, either with or without defined order. [Jan, Oct 29, 2002]
/**
* This is the abstract <i>Command</i> protocol.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.1, 10/29/02
*
* @see Command
*/
public abstract aspect CommandProtocol {
////////////////////////////////
// Invoker -> Command mapping //
////////////////////////////////
/**
* stores the mapping between CommandInvokers and Commands
*/
private WeakHashMap mappingInvokerToCommand = new WeakHashMap();
/**
* Sets a new command for an invoker
*
* @param invoker the object which will invoke the command
* @param command the command to be set
* @returns the former command
*/
public Object setCommand(CommandInvoker invoker, Command command) {
return mappingInvokerToCommand.put(invoker, command);
}
/**
* Removes a command from an invoker
*
* @param invoker the object which will no longer invoke the command
* @param command the command to be removed
* @returns the former command
*/
public Object removeCommand(CommandInvoker invoker) {
return setCommand(invoker, null);
}
/**
* Returns the command for an invoker
*
* @param invoker the object for which to return the command
* @returns the current command for the invoker
*/
public Command getCommand(CommandInvoker invoker) {
return (Command) mappingInvokerToCommand.get(invoker);
}
/////////////////////////////////
// Command -> Receiver mapping //
/////////////////////////////////
/**
* stores the mapping between Coammnds and Receivers
*/
private WeakHashMap mappingCommandToReceiver = new WeakHashMap();
/**
* Sets a new receiver for a command
*
* @param command the command to be set
* @param receiver the object to be manipulated by the command's
* execute() method
* @returns the former receiver
*/
public Object setReceiver(Command command, CommandReceiver receiver) {
return mappingCommandToReceiver.put(command, receiver);
}
/**
* Returns the receiver for a particular command
*
* @param invoker the object for which to return the command
* @returns the current command for the invoker
*/
public CommandReceiver getReceiver(Command command) {
return (CommandReceiver) mappingCommandToReceiver.get(command);
}
///////////////////////////////////////
// Command Execution via PC & advice //
///////////////////////////////////////
/**
* The join points after which to execute the command.
* This replaces the normally scattered myCommand.execute() calls.
*
* @param invoker the object invoking the command
*/
protected abstract pointcut commandTrigger(CommandInvoker invoker);
/**
* Calls <code>executeCommand()</code> when the command is triggered.
*
* @param invoker the object invoking the command
*/
after(CommandInvoker invoker): commandTrigger(invoker) {
Command command = getCommand(invoker);
if (command != null) {
CommandReceiver receiver = getReceiver(command);
command.executeCommand(receiver);
} else {
// Do nothing: This Invoker has no associated command
}
}
//////////////////////////////////
// setCommand() via PC & advice //
//////////////////////////////////
/**
* The join points after which to set a command for an invoker.
* This replaces the normally scattered myInvoker.add(Command) calls.
* The pointcut is provided in addition to the setCommand() method above,
* to allow all pattern code to be removed from concrete invokers.
*
* This PC is non-abstract, to make it optional for sub-aspcects to define
* it.
*
* @param invoker the invoker to attach the command to
* @param command the command to be attached to the invoker
*/
protected pointcut setCommandTrigger(CommandInvoker invoker, Command command);
/**
* Calls <code>addCommand()</code> when a command should be set.
*
* @param invoker the invoker to attach the command to
* @param command the command to be attached to the invoker
*/
after(CommandInvoker invoker, Command command): setCommandTrigger(invoker, command) { // TODO: is "before" a better choice?
if (invoker != null)
setCommand(invoker, command);
// TODO: throw exception in else case?
}
/////////////////////////////////////
// removeCommand() via PC & advice //
/////////////////////////////////////
/**
* The join points after which to remove a command from an invoker.
* This replaces the normally scattered myInvoker.remove(Command) calls.
* The pointcut is provided in addition to the removeCommand() method
* above, to allow all pattern code to be removed from concrete invokers.
*
* This PC is non-abstract, to make it optional for sub-aspcects to define
* it.
*
* @param invoker the invoker to remove the command from
*/
protected pointcut removeCommandTrigger(CommandInvoker invoker);
/**
* Calls <code>removeCommand()</code> when a command should be removed.
*
* @param invoker the invoker to remove the command from
*/
after(CommandInvoker invoker): removeCommandTrigger(invoker) { // TODO: is "before" a better choice?
if (invoker != null)
removeCommand(invoker);
// TODO: throw exception in else case?
}
////////////////////////////////////////////
// Command default method implementations //
////////////////////////////////////////////
/**
* Provides a deault implementation for the isExecutable method defined
* in the Command interface.
*
* @returns true (default implementation). Can be overwritten by concrete
* aspects or even concrete commands.
*/
public boolean ca.ubc.cs.spl.pattern.library.Command.isExecutable() {
return true;
}
////////////////////////////////////////////////////////////////
// Calling specialized execute() instead of generic execute() //
////////////////////////////////////////////////////////////////
public final void Command.execute() {} // this prevents anyone from implementing this method instead of the specialized version. Invokers can call it though
protected pointcut callGenericExecute(Command command):
( call(void Command+.execute())) && target(command);
after(Command command): callGenericExecute(command) { // TODO: around?
command.executeCommand(getReceiver(command));
}
}
</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZCommandReceiver.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package ca.ubc.cs.spl.pattern.library;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.patterns.
*
* Contributor(s):
*/
/**
* This interface is used by extending aspects to say what types
* can be Receivers (i.e. manipulated by a command object receiving an
* executeCommand() call).
* This role is assigned by concrete sub-aspects of the <code>CommandProtocol
* </code> pattern aspect.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.1, 10/29/02
*
* @see CommandProtocol
*/
public interface CommandReceiver { } </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZLeaf.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.java;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
/**
* Implements a concrete element of the aggregate strcuture. This is a
* terminal binary tree element (leaf).
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*
* @see Node
* @see NodeVisitor
*/
public class Leaf implements Node {
/**
* the value stored in this leaf
*/
protected int value;
/**
* Accepts a visitor and calls <code>visitRegularNode(Node) on it.
*
* @param nv the NodeVisitor that is to be accepted.
*/
public void accept(NodeVisitor nv) {
nv.visitLeaf(this);
}
/**
* Creates a new Leaf with the given value.
*
* @param v the value of the leaf
*/
public Leaf(int v) {
value = v;
}
/**
* Accessor for the leaf's value
*
* @returns the leaf's value
*/
public int getValue() {
return value;
}
}</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZMain.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.java;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
/**
* Implements the driver for the Visitor design pattern example.<p>
*
* Intent: <i>Represents an operation to be performed on the elements of an
* object structure. Visitor lets you define a new operation without changing
* the classes of the elements on which it operates</i><p>
*
* Participating classes are <code>SumVisitor</code> and
* <code>TraversalVisitor</code> as <i>ConcreteVisitor</i>s, implementing the
* <code>NodeVisitor</code> interface. <BR>
* <code>RegularNode</code> and <code>Leaf</code> are <i>ConcreteElement</i>s,
* implementing the <code>Node</code> interface. <p>
*
* In this example, Node, RegularNode and Leaf build up a binary tree that has
* int values as leafs. SumVisitor is a NodeVisitor that collects the sum of
* elements in the leafs (should be 6). TraversalVisitor is a visitor that
* collects a description of the tree like {{1,2},3}
*
* <p><i>This is the Java version.</i><p>
*
* Note that <UL>
* <LI> Every visitor (even the inteface) has to know of each possible element
* type in the object structure.
* <LI> Nodes need to know of the visitor interface; they have to implement the
* accept(NodeVisitor) method.
* </UL>
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*
* @see Node
* @see RegularNode
* @see Leaf
* @see NodeVisitor
* @see SumVisitor
* @see TraversalVisitor
*/
public class Main {
/**
* Implements the driver for the Visitor design pattern example.<p>
*
* In this example, Node, RegularNode and Leaf build up a binary tree that has
* int values as leafs. SumVisitor is a NodeVisitor that collects the sum of
* elements in the leafs (should be 6). TraversalVisitor is a visitor that
* collects a description of the tree like {{1,2},3}
*
* @param args the command-line parameters, unused
*/
public static void main(String[] args) {
System.out.println("Building the tree (1): leaves");
Leaf one = new Leaf(1);
Leaf two = new Leaf(2);
Leaf three = new Leaf(3);
System.out.println("Building the tree (1): regular nodes");
RegularNode regN = new RegularNode(one, two);
RegularNode root = new RegularNode(regN, three);
System.out.println("The tree now looks like this: ");
System.out.println(" regN ");
System.out.println(" / \\ ");
System.out.println(" regN 3 ");
System.out.println(" / \\ ");
System.out.println(" 1 2 ");
System.out.println("Visitor 1: SumVisitor, collects the sum of leaf");
System.out.println("values. Result should be 6.");
SumVisitor sumVisitor = new SumVisitor();
root.accept(sumVisitor);
System.out.println(sumVisitor.report());
System.out.println("Visitor 2: TraversalVisitor, collects a tree");
System.out.println("representation. Result should be {{1,2},3}.");
TraversalVisitor traversalVisitor = new TraversalVisitor();
root.accept(traversalVisitor);
System.out.println(traversalVisitor.report());
}
}</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZMyVisitor.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.aspectj;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
import ca.ubc.cs.spl.pattern.library.VisitorProtocol;
/**
* Implements a concrete visitor pattern instance. This aspect assings
* the roles to the participants.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*/
public aspect MyVisitor extends VisitorProtocol {
/**
* Assigns the <code>VisitorNode</code> role to <code>Node</code>
*/
declare parents: Node implements VisitorNode;
/**
* Assigns the <code>VRegularNode</code> role to <code>RegularNode</code>
*/
declare parents: RegularNode implements VRegularNode;
/**
* Assigns the <code>VLeaf</code> role to <code>Leaf</code>
*/
declare parents: Leaf implements VLeaf;
}
</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZNode.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.java;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
/**
* Defines the interface for nodes that can accept visitors.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*
* @see RegularNode
* @see Leaf
* @see NodeVisitor
*/
public interface Node {
/**
* Accepts a visitor according to GoF.
*
* @param nv the NodeVisitor that is to be accepted.
*/
public void accept(NodeVisitor nv);
}
</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZNodeVisitor.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.java;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
/**
* Defines the interface for visitors that operate on binary trees consisting
* of Leafs and RegularNodes.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*
* @see Node
* @see Leaf
* @see RegularNode
*/
public interface NodeVisitor {
/**
* Visits a RegularNode, which is a non-terminal binary tree node.
*
* @param node the regular node
*/
public void visitRegularNode(Node node);
/**
* Visits a Leaf, which is a terminal tree node.
*
* @param node the leaf
*/
public void visitLeaf(Node node);
/**
* Returns the result of the visitor's operation
*
* @returns a string describing the result of this visitor's operation.
*/
public String report();
}</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZRegularNode.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.java;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
/**
* Implements a concrete element of the aggregate strcuture. This is a
* non-terminal binary tree element.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*
* @see Node
* @see NodeVisitor
*/
public class RegularNode implements Node {
/**
* the left subtree
*/
protected Node left;
/**
* the right subtree
*/
protected Node right;
/**
* Accepts a visitor and calls <code>visitRegularNode(Node) on it.
*
* @param nv the NodeVisitor that is to be accepted.
*/
public void accept(NodeVisitor nv) {
nv.visitRegularNode(this);
}
/**
* Accessor for the left subtree.
*
* @returns the left subtree.
*/
public Node getLeft() {
return left;
}
/**
* Accessor for the right subtree.
*
* @returns the right subtree.
*/
public Node getRight() {
return right;
}
/**
* Creates a non-terminal node of a binary tree.
*
* @param l the new left subtree.
* @param l the new left subtree.
*/
public RegularNode(Node l, Node r) {
left = l;
right = r;
}
}</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZSampleComposite.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.testcomposite.aspectj;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
import java.io.PrintStream;
import java.util.Enumeration;
import ca.ubc.cs.spl.pattern.library.CompositeProtocol;
/**
* Implements a concrete instance of the composite design pattern.<p>
*
* It maintains the mapping between composites and their children, defines the
* component, composite, and leaf roles, and implements facilities to
* implements methods that work on the whole aggregate structure.
*
* <p><i>This is the AspectJ version.</i><p>
*
* Each concrete subaspect does the following things: <UL>
* <LI> Define which classes are Components and Leafs
* <LI> (optional) Define methods that operate on the whole aggregate
* structure (using visitors)
* </UL>
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 05/13/02
*
* @see Component
* @see CompositeA
* @see LeafB
*/
public aspect SampleComposite extends CompositeProtocol {
/**
* Assigns the Composite role to <code>CompositeA</code>
*/
declare parents: Directory implements Composite; // Role Pattern: Assigning Roles
/**
* Assigns the Leaf role to <code>LeafB</code>
*/
declare parents: File implements Leaf; // Role Pattern: Assigning Roles
// Test1: Attaching an operation with arguments
/**
* helper variable to store recursion depth for pretty printing
*/
private static int indent = 0;
/**
* Print a number of spaces according to the current recursion depth
*/
private static void indent() {
for (int i=0; i<indent; i++)
System.out.print(" ");
}
/*
public int sizeOnDisk(Component c) {
return c.sizeOnDisk();
}
private int Component.sizeOnDisk() {
Enumeration e = SampleComposite.aspectOf().recurseFunction(this, new FunctionVisitor() {
public Object doFunction(Component c) {
return new Integer(c.sizeOnDisk());
}
});
int sum =0;
while (e.hasMoreElements()) {
sum += ((Integer)e.nextElement()).intValue();
}
return sum;
}
private int File.sizeOnDisk() {return id;}
*/
public int sizeOnDisk(Component c) { // Does not work
return c.sizeOnDisk();
}
private int Component.sizeOnDisk() {return 0;}
private int Directory.sizeOnDisk() {
int sum = 0;
java.util.Enumeration children;
for (children = SampleComposite.aspectOf().getAllChildren(this); children.hasMoreElements(); ) {
sum += ((Component)children.nextElement()).sizeOnDisk();
}
return sum;
}
private int File.sizeOnDisk() { return id; }
/* public int sizeOnDisk(Component c) { // Works
int sum = 0;
if (c instanceof File) {
sum = ((File)c).id;
} else if (c instanceof Directory) {
java.util.Enumeration children;
for (children = SampleComposite.aspectOf().getAllChildren(c); children.hasMoreElements(); ) {
sum += sizeOnDisk((Component)children.nextElement());
}
}
return sum;
}
*/
/**
* Provides a client-accessible method that pretty-prints the
* structure of the aggregate structure using a Visitor
*
* @param s the PrintStram to print to
*/
public void Component.printStructure(PrintStream s) {
indent();
s.println("<Component>"+this);
}
/**
* Implements <code>printStructure</code> for Composites: The indent
* is appropriately updated and the method call is forwarded to all
* children.
*
* @param s the PrintStram to print to
*/
public void Composite.printStructure(final PrintStream s) {
indent();
s.println("<Composite>"+this);
indent +=4;
SampleComposite.aspectOf().recurseOperation(this, new Visitor() { public void doOperation(Component c) { c.printStructure(s); } } );
indent -=4;
}
/**
* Implements <code>printStructure</code> for Leafs.
*
* @param s the PrintStram to print to
*/
public void Leaf.printStructure(PrintStream s) {
indent();
s.println("<Leaf>"+this);
}
// Test2: Collecting statistics on the structure (aggregation)
/**
* Provides a client-accessible method that pretty-prints the
* structure of the aggregate structure using a FunctionVisitor.
* Calculates the sum of all Leaf IDs in the structure
*
* @returns the sum of leaf ids of all elements in this structure
*/
public int Component.subSum() {
return 0;
}
/**
* Implements <code>subSum()</code> for Composites: The method call
* is forwarded to all children, then the results are summed up.
*
* @returns the sum of leaf ids of all elements in this structure
*/
public int Composite.subSum() { // Collects the sum of all Leaves in the structure
Enumeration enum = SampleComposite.aspectOf().recurseFunction(this, new FunctionVisitor() {
public Object doFunction(Component c) {
return new Integer(c.subSum());
}
});
int sum = 0;
while (enum.hasMoreElements()) {
sum += ((Integer) enum.nextElement()).intValue();
System.out.println("Sum = "+sum);
}
return sum;
}
/**
* Implements <code>subSum()</code> for Leafs: Simply returns
* the Leaf's ID.
*
* @returns the leaf id
*/
public int File.subSum() {
return id;
}
}
</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZSumVisitor.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.java;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
/**
* Implements a concrete visitor that collects the sum of all leaf values in
* the tree.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*
* @see Node
* @see Leaf
* @see RegularNode
*/
public class SumVisitor implements NodeVisitor {
/**
* the colleced sum of leaf values
*/
protected int sum = 0;
/**
* Visits a RegularNode, which is a non-terminal binary tree node.
*
* @param node the regular node
*/
public void visitRegularNode(Node node) {
RegularNode rnode = (RegularNode) node;
rnode.left.accept(this);
rnode.right.accept(this);
}
/**
* Visits a Leaf, which is a terminal tree node.
*
* @param node the leaf
*/
public void visitLeaf(Node node) {
Leaf leaf = (Leaf) node;
sum += leaf.getValue();
}
/**
* Returns the result of the visitor's operation
*
* @returns a string describing the result of this visitor's operation.
*/
public String report() {
return ">>> SumVisitor collected a sum of "+sum;
}
}</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZTraversalVisitor.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">package examples.visitor.java;
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This file is part of the design patterns project at UBC
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* either http:*www.mozilla.org/MPL/ or http:*aspectj.org/MPL/.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is ca.ubc.cs.spl.pattern.
*
* Contributor(s):
*/
/**
* Implements a concrete visitor that collects string representation of the
* tree.
*
* @author Jan Hannemann
* @author Gregor Kiczales
* @version 1.0, 06/13/02
*
* @see Node
* @see Leaf
* @see RegularNode
*/
public class TraversalVisitor implements NodeVisitor {
/**
* contains the accumulated result
*/
protected String result = "";
/**
* Visits a RegularNode, which is a non-terminal binary tree node.
*
* @param node the regular node
*/
public void visitRegularNode(Node node) {
RegularNode rnode = (RegularNode) node;
result += "{";
rnode.getLeft().accept(this);
result += ",";
rnode.getRight().accept(this);
result += "}";
}
/**
* Visits a Leaf, which is a terminal tree node.
*
* @param node the leaf
*/
public void visitLeaf(Node node) {
Leaf leaf = (Leaf) node;
result += leaf.getValue();
}
/**
* Returns the result of the visitor's operation
*
* @returns a string describing the result of this visitor's operation.
*/
public String report() {
return ">>> TraversalVisitor traversed the tree to: "+result;
}
}</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00ZVisitor.java2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><TEXTAREA name="code" class="java" rows="16" cols="100">public abstract aspect Visitor
{
// To make sure that all visitors are treated equally and can be
// passed on as arguments, we define an interface for them:
//
// Defining the method signatures here reduces reusability of
// the abstract aspect, but ensures type safety
interface VNode {}
interface VRegularNode extends VNode{}
interface VLeaf extends VNode {}
public interface NodeVisitor
{
public void visitRegularNode(VNode node);
public void visitLeaf(VNode node);
public String report();
}
// The individual accept() code is attached to the appropriate
// classes in the element structure:
public void VNode.accept(NodeVisitor nv)
{}
public void VRegularNode.accept(NodeVisitor nv)
{ nv.visitRegularNode(this); }
public void VLeaf.accept(NodeVisitor nv)
{ nv.visitLeaf(this); }
}</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00Zfiles.lst2004-03-24T16:00:00Z2004-03-24T16:00:00Z<br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>2004-03-24T16:00:00Z