/*
 Copyright (C) 2008 Richard Gomes

 This source code is release under the BSD License.

 This file is part of JQuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://jquantlib.org/

 JQuantLib is free software: you can redistribute it and/or modify it
 under the terms of the JQuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.

 JQuantLib is based on QuantLib. http://quantlib.org/
 When applicable, the original copyright notice follows this notice.
 */

/*
 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
 Copyright (C) 2003, 2004, 2005, 2006, 2007 StatPro Italia srl

 This file is part of QuantLib, a free-software/open-source library
 for financial quantitative analysts and developers - http://quantlib.org/

 QuantLib is free software: you can redistribute it and/or modify it
 under the terms of the QuantLib license.  You should have received a
 copy of the license along with this program; if not, please email
 . The license is also available online at
 .

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the license for more details.
 */

package org.jquantlib.quotes;

import java.util.List;

import org.jquantlib.util.Observable;
import org.jquantlib.util.Observer;
import org.jquantlib.util.WeakReferenceObservable;

/**
 * Shared handle to an observable
 * 

* All copies of an instance of this class refer to the same observable by means * of a relinkable weak reference. When such pointer is relinked to another * observable, the change will be propagated to all the copies. * * @author Richard Gomes */ public class Handle implements Observable { ///////////////////////////////////////////////////////////////////////////////////////////////// // // In QL/C++, Handle has operators which return the inner Link class, performing // a call to currentLink() behind the scenes. This is pretty handy from the calling // code because you can simply dereference a Handle and (like magic!) call methods // from the parameterized class. // // In Java we are obliged to explicitly call currentLink() in order to do the same thing. // // The difficulty arises when we need to register Observers. // // In the current implementation, we hide class Link from outside world and we only expose // the Handle itself, which implements Observable. Doing this way, the calling Java code // does not need to decide which object is really the Observer object because class Handle // is responsible for hiding this implementation details from outside world and properly // forwarding notifications to external Observers as expected. // ///////////////////////////////////////////////////////////////////////////////////////////////// static private final String EMPTY_HANDLE = "empty Handle cannot be dereferenced"; // TODO: message // // final private fields // /** * Responsible for forwarding notifications coming from the Observable object to * objects registering as Observers of this instance */ final private Link link; // // private fields // private T observable; private boolean isObserver = false; // // public constructors // public Handle() { this.link = new Link(this); this.observable = null; // just for verbosity this.isObserver = true; } public Handle(final T observable) { this.link = new Link(this); internalLinkTo(observable, true); } public Handle(final T observable, final boolean registerAsObserver) { this.link = new Link(this); internalLinkTo(observable, registerAsObserver); } // // final public methods // final public boolean empty() /* @ReadOnly */ { return (this.observable==null); } final public T currentLink() { return this.observable; } // // public methods // public void linkTo(final T observable) { throw new UnsupportedOperationException(); } public void linkTo(final T observable, final boolean registerAsObserver) { throw new UnsupportedOperationException(); } // // protected final methods // final protected void internalLinkTo(final T observable) { this.internalLinkTo(observable, true); } final protected void internalLinkTo(final T observable, final boolean registerAsObserver) { if ((this.observable!=observable) || (this.isObserver!=registerAsObserver)) { if (this.observable!=null && this.isObserver) { this.observable.deleteObserver(link); } this.observable = observable; this.isObserver = registerAsObserver; if (this.observable!=null && this.isObserver) { this.observable.addObserver(link); } if (this.observable!=null) { this.observable.notifyObservers(); } } } // // overrides Object // @Override public String toString() { return observable==null ? "null" : observable.toString(); } // // implements Observable // @Override public final void addObserver(final Observer observer) { //XXX QL.require(observable!=null, EMPTY_HANDLE); link.addObserver(observer); } @Override public final int countObservers() { //XXX QL.require(observable!=null, EMPTY_HANDLE); return link.countObservers(); } @Override public final void deleteObserver(final Observer observer) { //XXX QL.require(observable!=null, EMPTY_HANDLE); link.deleteObserver(observer); } @Override public final void notifyObservers() { //XXX QL.require(observable!=null, EMPTY_HANDLE); link.notifyObservers(); } @Override public final void notifyObservers(final Object arg) { //XXX QL.require(observable!=null, EMPTY_HANDLE); link.notifyObservers(arg); } @Override public final void deleteObservers() { //XXX QL.require(observable!=null, EMPTY_HANDLE); link.deleteObservers(); } @Override public final List getObservers() { //XXX QL.require(observable!=null, EMPTY_HANDLE); return link.getObservers(); } // // private final inner classes // /** * A Link is responsible for observing the Observable object passed to Handle during it's construction * or another Observable passed to {@link Handle#linkTo(Observable)} methods. *

* So, the ditto Observable notifies its Observers, a Link instance is notified, which ultimately * is responsible for forwarding this notification to a list of external Observers. */ final private class Link extends WeakReferenceObservable implements Observer { private Link(final Observable observable) { super(observable); } @Override public void update() { if (observable!=null) { super.notifyObservers(); } } } }

Ads help maintain this website.