carfield.com.hk <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.txt 2008-03-17T17:25:16Z 2008-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/>(jan@cs.ubc.ca). 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:16Z Command.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &lt;i&gt;Command&lt;/i&gt; 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:00Z CommandInvoker.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &lt;code&gt;CommandProtocol * &lt;/code&gt; 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:00Z CommandProtocol.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &lt;i&gt;Command&lt;/i&gt; protocol. * * @author Jan Hannemann * @author Gregor Kiczales * @version 1.1, 10/29/02 * * @see Command */ public abstract aspect CommandProtocol { //////////////////////////////// // Invoker -&gt; 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 -&gt; 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 &amp; 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 &lt;code&gt;executeCommand()&lt;/code&gt; 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 &amp; 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 &lt;code&gt;addCommand()&lt;/code&gt; 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 &quot;before&quot; a better choice? if (invoker != null) setCommand(invoker, command); // TODO: throw exception in else case? } ///////////////////////////////////// // removeCommand() via PC &amp; 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 &lt;code&gt;removeCommand()&lt;/code&gt; when a command should be removed. * * @param invoker the invoker to remove the command from */ after(CommandInvoker invoker): removeCommandTrigger(invoker) { // TODO: is &quot;before&quot; 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())) &amp;&amp; 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:00Z CommandReceiver.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &lt;code&gt;CommandProtocol * &lt;/code&gt; 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:00Z Leaf.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &lt;code&gt;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:00Z Main.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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.&lt;p&gt; * * Intent: &lt;i&gt;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&lt;/i&gt;&lt;p&gt; * * Participating classes are &lt;code&gt;SumVisitor&lt;/code&gt; and * &lt;code&gt;TraversalVisitor&lt;/code&gt; as &lt;i&gt;ConcreteVisitor&lt;/i&gt;s, implementing the * &lt;code&gt;NodeVisitor&lt;/code&gt; interface. &lt;BR&gt; * &lt;code&gt;RegularNode&lt;/code&gt; and &lt;code&gt;Leaf&lt;/code&gt; are &lt;i&gt;ConcreteElement&lt;/i&gt;s, * implementing the &lt;code&gt;Node&lt;/code&gt; interface. &lt;p&gt; * * 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} * * &lt;p&gt;&lt;i&gt;This is the Java version.&lt;/i&gt;&lt;p&gt; * * Note that &lt;UL&gt; * &lt;LI&gt; Every visitor (even the inteface) has to know of each possible element * type in the object structure. * &lt;LI&gt; Nodes need to know of the visitor interface; they have to implement the * accept(NodeVisitor) method. * &lt;/UL&gt; * * @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.&lt;p&gt; * * 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(&quot;Building the tree (1): leaves&quot;); Leaf one = new Leaf(1); Leaf two = new Leaf(2); Leaf three = new Leaf(3); System.out.println(&quot;Building the tree (1): regular nodes&quot;); RegularNode regN = new RegularNode(one, two); RegularNode root = new RegularNode(regN, three); System.out.println(&quot;The tree now looks like this: &quot;); System.out.println(&quot; regN &quot;); System.out.println(&quot; / \\ &quot;); System.out.println(&quot; regN 3 &quot;); System.out.println(&quot; / \\ &quot;); System.out.println(&quot; 1 2 &quot;); System.out.println(&quot;Visitor 1: SumVisitor, collects the sum of leaf&quot;); System.out.println(&quot;values. Result should be 6.&quot;); SumVisitor sumVisitor = new SumVisitor(); root.accept(sumVisitor); System.out.println(sumVisitor.report()); System.out.println(&quot;Visitor 2: TraversalVisitor, collects a tree&quot;); System.out.println(&quot;representation. Result should be {{1,2},3}.&quot;); 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:00Z MyVisitor.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &lt;code&gt;VisitorNode&lt;/code&gt; role to &lt;code&gt;Node&lt;/code&gt; */ declare parents: Node implements VisitorNode; /** * Assigns the &lt;code&gt;VRegularNode&lt;/code&gt; role to &lt;code&gt;RegularNode&lt;/code&gt; */ declare parents: RegularNode implements VRegularNode; /** * Assigns the &lt;code&gt;VLeaf&lt;/code&gt; role to &lt;code&gt;Leaf&lt;/code&gt; */ 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:00Z Node.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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:00Z NodeVisitor.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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:00Z RegularNode.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &lt;code&gt;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:00Z SampleComposite.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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.&lt;p&gt; * * 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. * * &lt;p&gt;&lt;i&gt;This is the AspectJ version.&lt;/i&gt;&lt;p&gt; * * Each concrete subaspect does the following things: &lt;UL&gt; * &lt;LI&gt; Define which classes are Components and Leafs * &lt;LI&gt; (optional) Define methods that operate on the whole aggregate * structure (using visitors) * &lt;/UL&gt; * * @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 &lt;code&gt;CompositeA&lt;/code&gt; */ declare parents: Directory implements Composite; // Role Pattern: Assigning Roles /** * Assigns the Leaf role to &lt;code&gt;LeafB&lt;/code&gt; */ 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&lt;indent; i++) System.out.print(&quot; &quot;); } /* 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(&quot;&lt;Component&gt;&quot;+this); } /** * Implements &lt;code&gt;printStructure&lt;/code&gt; 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(&quot;&lt;Composite&gt;&quot;+this); indent +=4; SampleComposite.aspectOf().recurseOperation(this, new Visitor() { public void doOperation(Component c) { c.printStructure(s); } } ); indent -=4; } /** * Implements &lt;code&gt;printStructure&lt;/code&gt; for Leafs. * * @param s the PrintStram to print to */ public void Leaf.printStructure(PrintStream s) { indent(); s.println(&quot;&lt;Leaf&gt;&quot;+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 &lt;code&gt;subSum()&lt;/code&gt; 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(&quot;Sum = &quot;+sum); } return sum; } /** * Implements &lt;code&gt;subSum()&lt;/code&gt; 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:00Z SumVisitor.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 &quot;&gt;&gt;&gt; SumVisitor collected a sum of &quot;+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:00Z TraversalVisitor.java 2004-03-24T16:00:00Z 2004-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 &quot;License&quot;); 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 &quot;AS IS&quot; 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 = &quot;&quot;; /** * 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 += &quot;{&quot;; rnode.getLeft().accept(this); result += &quot;,&quot;; rnode.getRight().accept(this); result += &quot;}&quot;; } /** * 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 &quot;&gt;&gt;&gt; TraversalVisitor traversed the tree to: &quot;+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:00Z Visitor.java 2004-03-24T16:00:00Z 2004-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:00Z files.lst 2004-03-24T16:00:00Z 2004-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