All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bibliothek.gui.dock.util.extension.ExtensionManager Maven / Gradle / Ivy

The newest version!
/*
 * 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) 2010 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
 * [email protected]
 * CH - Switzerland
 */
package bibliothek.gui.dock.util.extension;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import bibliothek.gui.DockController;

/**
 * Manages a set of {@link Extension}s.
 * @author Benjamin Sigg
 */
public class ExtensionManager {
	/** the controller in whose realm this manager works */
	private DockController controller;
	
	/** all the extensions of this manager */
	private List extensions = new ArrayList();
	
	/** whether the extensions are installed or not */
	private boolean alive = false;
	
	/** all shared extensions */
	private Map, Share> shared = new HashMap, Share>();
	
	/**
	 * Creates a new manager.
	 * @param controller the controller in whose realm this manager works
	 */
	public ExtensionManager( DockController controller ){
		this.controller = controller;
		tryLoadDefaultExtensions();
	}
	
	/**
	 * Tries to load the standard extensions that are developed alongside with the
	 * main-framework.
	 */
	protected void tryLoadDefaultExtensions(){
		String[] list = { 
				"glass.eclipse.GlassExtension",
				"bibliothek.gui.ToolbarExtension" };
		for( String className : list ){
			try {
				tryLoadExtension( className );
			} catch( ClassNotFoundException e ) {
				// ignore
			} catch( InstantiationException e ) {
				e.printStackTrace();
			} catch( IllegalAccessException e ) {
				// ignore
			}
		}
	}
	
	private void tryLoadExtension( String className ) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		Class clazz = Class.forName( className );
		Object extension = clazz.newInstance();
		if( extension instanceof Extension ){
			add( (Extension)extension );
		}
	}
	
	/**
	 * Adds extension to the list of extensions.
	 * @param extension the new extension
	 */
	public void add( Extension extension ){
		extensions.add( extension );
		if( alive ){
			extension.install( controller );
		}
	}
	
	/**
	 * Removes extension from the list of extensions.
	 * @param extension the extension to remove
	 */
	public void remove( Extension extension ){
		if( extensions.remove( extension ) ){
			if( alive ){
				extension.uninstall( controller );
			}
		}
	}
	
	/**
	 * Gets a list of all extensions that are currently known to this manager.
	 * @return the list of extensions
	 */
	public Extension[] getExtensions(){
		return extensions.toArray( new Extension[ extensions.size() ] );
	}
	
	/**
	 * Loads all extensions matching name.
	 * @param  the type of extensions that is loaded
	 * @param name the name of the extensions
	 * @return a list containing all non-null extensions, may be empty
	 */
	public  List load( ExtensionName name ){
		List result = new ArrayList();
		for( Extension extension : extensions ){
			Collection es = extension.load( controller, name );
			if( es != null ){
				result.addAll( es );
			}
		}
		return result;
	}
	
	/**
	 * Creates a new {@link SharedExtension} object which uses name as key to read 
	 * extensions. The {@link SharedExtension} object can be {@link SharedExtension#bind() bound} 
	 * and {@link SharedExtension#unbind() unbound} at any time, it can be reused.
	 * @param name the name of the extension to share
	 * @return the shared extensions
	 */
	public  SharedExtension share( final ExtensionName name ){
		return new SharedExtension(){
			private int bound = 0;
			
			@SuppressWarnings("unchecked")
			public void bind(){
				if( bound == 0 ){
					Share share = (Share)shared.get( name );
					if( share == null ){
						share = new Share( name );
					}
					share.bind();
				}
				bound++;
			}
			
			@SuppressWarnings("unchecked")
			public void unbind(){
				if( bound == 0 ){
					throw new IllegalStateException( "cannot unbind, counter is already 0" );
				}
				bound--;
				if( bound == 0 ){
					Share share = (Share)shared.get( name );
					if( share != null ){
						share.unbind();
					}
				}
			}
			
			@SuppressWarnings("unchecked")
			public List get(){
				if( bound == 0 ){
					throw new IllegalStateException( "SharedExtension is not bound" );
				}
				Share share = (Share)shared.get( name );
				return share.get();
			}
			
			public Iterator iterator(){
				return get().iterator();
			}
			
			public ExtensionName getName(){
				return name;
			}
		};
	}
	
	/**
	 * Represents a shared set of extensions.
	 * @author Benjamin Sigg
	 * @param  the type of object that is shared
	 */
	private class Share{
		private int bound = 0;
		private List extensions;
		private ExtensionName name;
		
		/**
		 * Creates a new cache.
		 * @param name the key of the extensions
		 */
		public Share( ExtensionName name ){
			this.name = name;
		}
		
		/**
		 * Connects this cache.
		 */
		public void bind(){
			if( bound == 0 ){
				shared.put( name, this );
			}
			bound++;
		}
		
		/**
		 * Disconnects this cache.
		 */
		public void unbind(){
			bound--;
			if( bound == 0 ){
				shared.remove( name );
			}
		}
		
		/**
		 * Gets the content of this cache.
		 * @return the content
		 */
		public List get(){
			if( extensions == null ){
				extensions = Collections.unmodifiableList( load( name ) );
			}
			return extensions;
		}
	}
	
	/**
	 * Starts up all extensions.
	 */
	public void init(){
		alive = true;
		for( Extension extension : extensions ){
			extension.install( controller );
		}
	}
	
	/**
	 * Stops and removes all extensions.
	 */
	public void kill(){
		if( alive ){
			alive = false;
			for( Extension extension : extensions ){
				extension.uninstall( controller );
			}
			extensions.clear();
		}
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy