carfield.com.hkCommand.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:00Z