Package org.locationtech.udig.catalog.util

Source Code of org.locationtech.udig.catalog.util.HandleListener

/*
*    uDig - User Friendly Desktop Internet GIS client
*    http://udig.refractions.net
*    (C) 2004, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*
*/
package org.locationtech.udig.catalog.util;

import java.lang.ref.WeakReference;

import org.locationtech.udig.catalog.IResolve;
import org.locationtech.udig.catalog.IResolveChangeEvent;
import org.locationtech.udig.catalog.IResolveChangeListener;
import org.locationtech.udig.catalog.IResolveDelta;
/**
* Easy example that listens to a specific IResolve.
* <p>
* <p>
* Will do its best to reduce the IResolveChangeEvent to:
* <ul>
* <li>start() - called after create with valid handle
* <li>stop() - called before remove while handle is still valid
* <li>dispose() - called after remove while handle is invalid
* <li>refresh() - called when handle has changed
* <li>replace() - called when handle is replaced
* <li>reset() - called when handle is replaced, and replacement is unknown
* </ul>
* </p>
* <p>
* Note 1: The IResolveDelta does not always include information about *your* handle. If your parent
* is being replaced - your direct replacement may not be available until you ask for it.
* </p>
* <p>
* Translation repalce with a null newResolve = reset. This indicates you need to find your handle
* again from first principles.
* </p>
* <p>
* Note 2: HandleListener only holds onto a IResolve with a weak reference. Although this protects
* you a little bit, you still need to remove zombie listeners from the catalog (they cannot do it
* themselves).
* </p>
* <p>
* However when the weak reference is cleaned up, we will notice and call dispose for you.
* </p>
*
* @author jgarnett
* @since 0.9.0
*/
public abstract class HandleListener implements IResolveChangeListener {
    private WeakReference<IResolve> reference;

    public HandleListener( IResolve handle ) {
        reference = new WeakReference<IResolve>(handle);
    }

    /**
     * Resolve the handle - will call dispose if handle has passed out of scope.
     */
    public IResolve getHandle() {
        if (reference == null)
            return null;
        if (reference.enqueue()) {
            dispose();
            return null;
        }
        IResolve handle = reference.get();
        if (handle == null) {
            dispose();
        }
        return null;
    }
    /**
     * Can be called during a repalce, or reset to switch this listener over to the new handle.
     *
     * @param handle
     * @return
     */
    public void setHandle( IResolve newHandle ) {
        reference.clear();
        reference = null;
        reference = new WeakReference<IResolve>(newHandle);
    }
    /** Called after create with valid handle */
    public abstract void start( IResolve handle );

    /** Called before remove while handle is still valid */
    public abstract void stop( IResolve handle );

    /** Called after remove while handle is invalid */
    public abstract void dispose();

    /** Called when handle has changed */
    public abstract void refresh( IResolve handle );

    /**
     * Handle is being replaced with newHandle.
     * <p>
     * Note: This method is called post change, the newHandle already exists in the catalog.
     * </p>
     * <p>
     * You have two options:
     * <ul>
     * <li>use setHandle( newHandle ) during your implemenation to <b>switch</b> over to the
     * newHandle
     * <li>remove this listener and set up a new one watching newHandle
     * </ul>
     * </p>
     */
    public abstract void replace( IResolve handle, IResolve newHandle );

    /**
     * This is a replace where the replacement is unknown.
     * <p>
     * This occurs when:
     * <ul>
     * <li>an IResolveChangeDelta indicates your is replaced
     * <li>an IResolveChangeDelta indicates you replaced
     * </ul>
     * </p>
     * <p>
     * In both cases you have two options:
     * <ul>
     * <li>Easy: find your replacement handle from first principles (ie look it up in the catalog)
     * <li>Harder: as an optimization you can try and look through the event information and locate
     * the delta for your parent. This delta may indicate your new parent, allowing you to locate
     * your "new" handle in a more timely fashion.
     * </ul>
     * </p>
     *
     * @param handle
     */
    public abstract void reset( IResolve handle, IResolveChangeEvent event );

    /** Actual listener implemtnation */
    final public void changed( IResolveChangeEvent event ) {
        IResolve handle = getHandle();
        if (handle == null) {
            dispose();
            return;
        }
        if (event.getResolve() == handle) {
            // simple case event mentions handle
            switch( event.getType() ) {
            case PRE_DELETE:
                stop(handle);
                return;
            case PRE_CLOSE:
                dispose();
                return;
            case POST_CHANGE:
            default:
                refresh(handle);
                return;
            }
        }
        IResolveDelta match = SearchResolveDeltaVisitor.search(handle, event);
        if (match == null) {
            return; // this event does not effect us
        }
        if (match.getResolve() == handle) {
            // simple case delta mentions handle
            switch( match.getKind() ) {
            case NO_CHANGE:
                return; // one of our childs must of changed ...
            case ADDED:
                start(handle);
                return;
            case REMOVED:
                dispose();
                return;
            case REPLACED:
                if (match.getNewResolve() != null) {
                    replace(handle, match.getNewResolve());
                } else {
                    reset(handle, event);
                }
                return;
            case CHANGED:
            default:
                refresh(handle);
                return;
            }
        }
        // our parent has changed
        switch( match.getKind() ) {
        case NO_CHANGE:
        case ADDED:
            return; // these do not make sense in this context
        case REMOVED:
            dispose(); // parent is being removed
            return;
        case REPLACED: // parent is replaced, reset handle
            reset(handle, event);
            return;
        case CHANGED:
        default:
            refresh(handle);
            return;
        }
    }
}
TOP

Related Classes of org.locationtech.udig.catalog.util.HandleListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.