/*
* @(#)WeakPropertyChangeListener.java
*
* Copyright (c) 2011 Werner Randelshofer, Goldau, Switzerland.
* All rights reserved.
*
* You may not use, copy or modify this file, except in compliance with the
* license agreement you entered into with Werner Randelshofer.
* For details see accompanying license terms.
*
* This class has been derived from WeakPropertyChangeListener.java,
* v 1.2 2005-06-20 18:26:16 by Paul Speed.
*
* Copyright (c) 2004, Paul Speed
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3) Neither the names "Progeeks", "Meta-JB", nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.monte.media.beans;
import java.beans.*;
import java.lang.ref.*;
/**
* Property change listener that holds weak reference to a
* target property change listener. If the weak reference
* becomes null (meaning the delegate has been GC'ed) then this
* listener will remove itself from any beans that it receives
* events from. It isn't perfect, but it's a lot better than
* nothing... and presumably beans that no longer send out events
* probably don't care if their listeners weren't properly cleaned
* up.
*
* Design pattern: Proxy.
*
* @author Paul Speed
* @version $Id: WeakPropertyChangeListener.java 299 2013-01-03 07:40:18Z werner $
*/
public class WeakPropertyChangeListener implements PropertyChangeListener {
private WeakReference<PropertyChangeListener> weakRef;
public WeakPropertyChangeListener(PropertyChangeListener target) {
this.weakRef = new WeakReference<PropertyChangeListener>(target);
}
/**
* Method that can be subclassed to provide additional remove
* support. Default implementation only supports StandardBeans.
*/
protected void removeFromSource(PropertyChangeEvent event) {
// Remove ourselves from the source
Object src = event.getSource();
try {
src.getClass().getMethod("removePropertyChangeListener", new Class[] {PropertyChangeListener.class}).invoke(src, this);
} catch (Exception ex) {
InternalError ie = new InternalError("Could not remove WeakPropertyChangeListener from "+src+".");
ie.initCause(ex);
throw ie;
}
}
@Override
public void propertyChange(PropertyChangeEvent event) {
PropertyChangeListener listener = (PropertyChangeListener) weakRef.get();
if (listener == null) {
removeFromSource(event);
return;
}
listener.propertyChange(event);
}
/**
* Returns the target of this proxy. Returns null if the target has been
* garbage collected.
*
* @return The target or null.
*/
public PropertyChangeListener getTarget() {
return weakRef.get();
}
@Override
public String toString() {
return super.toString()+"["+weakRef.get()+"]";
}
}