package ca.ubc.cs.spl.aspectPatterns.patternLibrary; /* -*- 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 https://www.mozilla.org/MPL/ or https://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.aspectPatterns. * * For more details and the latest version of this code, please see: * https://www.cs.ubc.ca/labs/spl/projects/aodps.html * * Contributor(s): */ import java.util.WeakHashMap; import java.util.Collection; import java.util.LinkedList; import java.util.Iterator; /** * Defines the general behavior of the Mediator design pattern. * * Each concrete sub-aspect of MediatorProtocol defines one kind of mediation * relationship. Within that kind of relationship, there can be any number * of Colleagues. * * The sub-aspect defines three things:
    * *
  1. what types can be Colleagues and Mediator
    * this is done using implements * *
  2. what operations on the Colleague trigger Mediator * updates.
    * This is done by concretizing the change(Colleague) * pointcut * *
  3. how to mediate
    * this is done by concretizing * notifyMediator(Colleague, Mediator) *
* * Note that in this implementation, the work of updating is a method * on the sub-aspect, not a method introduced on the Mediator. This * allows one class of object to be the Mediator in different kinds of * mediation relationships, each of which has a different updating * behavior. * * @author Jan Hannemann * @author Gregor Kiczales * @version 1.1, 02/12/04 */ public abstract aspect MediatorProtocol { /** * Declares the Colleague role. * Roles are modeled as (empty) interfaces. */ protected interface Colleague { } /** * Declares the Mediator role. * Roles are modeled as (empty) interfaces. */ protected interface Mediator { } /** * Stores the mapping between Colleaguess and * Mediators. For each Colleague, its Mediator * is stored. */ private WeakHashMap mappingColleagueToMediator = new WeakHashMap(); /** * Returns the Mediator of * a particular Colleague. Used internally. * * @param colleague the Colleague for which to return the mediator * @return the Mediator of the Colleague in question */ private Mediator getMediator(Colleague colleague) { Mediator mediator = (Mediator) mappingColleagueToMediator.get(colleague); return mediator; } /** * Sets the Mediator for a Colleague. This is a method * on the pattern aspect, not on any of the participants. * * @param colleague the Colleague to set a new Mediator for * @param mediator the new Mediator to set */ public void setMediator(Colleague colleague, Mediator mediator) { mappingColleagueToMediator.put(colleague, mediator); } /** * Defines what changes on Colleagues cause their Mediator * to be notified * * @param colleague the Colleague on which the change occured */ protected abstract pointcut change(Colleague colleague); /** * Call updateObserver to update each observer. */ after(Colleague c): change(c) { notifyMediator(c, getMediator(c)); } /** * Defines how the Mediator is to be updated when a change * to a Colleague occurs. To be concretized by sub-aspects. * * @param c the Colleague on which a change of interest occured * @param m the Mediator to be notifed of the change */ protected abstract void notifyMediator(Colleague c, Mediator m); }