/* * Bibliothek - DockingFrames * Library built on Java/Swing, allows the user to "drag and drop" * panels containing any Swing-Component the developer likes to add. * * Copyright (C) 2011 Benjamin Sigg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Benjamin Sigg * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui.dock.util; /** * A {@link ResourceRequest} describes an algorithm for finding or creating a resource by calling * a set of resource providers or factories in a specific order. * @author Benjamin Sigg * @param <T> the kind of resource this {@link ResourceRequest} provides */ public abstract class ResourceRequest<T> { /** the current answer to this request */ private T answer; /** whether this request has been answered */ private boolean answered = false; /** whether {@link #request()} has been called */ private boolean requesting = false; /** * Called when the requested resource changed. * @param previousResource the old resource object, may be <code>null</code> * @param newResource the new resource object, may be <code>null</code> */ protected abstract void answer( T previousResource, T newResource ); /** * Asks for a new resource and may trigger {@link #answer(Object, Object)}. This method * is made protected, subclasses can expose it, or write another method requiring additional * parameters, that calls this method. */ protected void request(){ answered = false; T old = answer; try{ requesting = true; executeRequestList(); } finally{ requesting = false; } if( old != answer ){ answer( old, answer ); } } /** * Tells whether {@link #answer(Object)} was called since the last {@link #request()}. * @return <code>true</code> if there is an answer */ public boolean isAnswered(){ return answered; } /** * Asks all sources for a new resource, needs to stop as soon * as one source called {@link #answer(Object)} (this can be queried * with {@link #isAnswered()}). */ protected abstract void executeRequestList(); /** * Asks this request to simulate a call to {@link #request()} which is * answered with <code>null</code> */ public void requestNull(){ if( answer != null ){ T old = answer; answer = null; answer( old, answer ); } } /** * Informs this request that <code>resource</code> should be user. This method * can be called more than once to use different resources. Subclasses may put strict demands on * what objects are valid resource objects. This method is not intended to be called in a generic way, callers * must be aware of the restrictions a subclass requires. * An answer must fulfill some rules: * * @param resource the new resource or <code>null</code> * @throws IllegalArgumentException if the resource does not met the specifications a subclass requires * @throws IllegalStateException if {@link #request()} is not currently executing */ public void answer( T resource ){ if( !requesting ){ throw new IllegalStateException( "not requesting a title" ); } validate( resource ); answered = true; answer = resource; } /** * Called by {@link #answer(Object)}, this method ensure that <code>resource</code> is a valid answer. The method * throws an {@link IllegalArgumentException} if not. * @param resource the resource to check * @throws IllegalArgumentException if <code>resource</code> is not a valid resource */ protected abstract void validate( T resource ); /** * Gets the last answer made to this request. * @return the last answer, may be <code>null</code> */ public T getAnswer(){ return answer; } }