Package bibliothek.gui.dock.common.intern

Source Code of bibliothek.gui.dock.common.intern.CommonSingleDockableFactory$Entry

/*
* 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) 2007 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.common.intern;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DockFactory;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CStation;
import bibliothek.gui.dock.common.SingleCDockable;
import bibliothek.gui.dock.common.SingleCDockableFactory;
import bibliothek.gui.dock.common.perspective.CPerspective;
import bibliothek.gui.dock.common.perspective.CommonElementPerspective;
import bibliothek.gui.dock.common.perspective.SingleCDockablePerspective;
import bibliothek.gui.dock.layout.LocationEstimationMap;
import bibliothek.gui.dock.perspective.PerspectiveDockable;
import bibliothek.gui.dock.station.support.PlaceholderStrategy;
import bibliothek.util.Filter;
import bibliothek.util.Version;
import bibliothek.util.filter.PresetFilter;
import bibliothek.util.xml.XElement;

/**
* This factory is used to create new {@link SingleCDockable}s using various
* {@link SingleCDockableFactory}s. This factory is accessed when a single
* dockable is missing in the cache of its owning {@link CControl}.
* @author Benjamin Sigg
*/
public class CommonSingleDockableFactory implements DockFactory<CommonDockable, CommonElementPerspective, CommonSingleDockableLayout>{
    public static final String BACKUP_FACTORY_ID = "ccontrol backup factory id";
   
    /** all the factories that are used */
    private List<Entry> factories = new ArrayList<Entry>();
   
    /** factories using one id only */
    private Map<String, Entry> singleIdFactories = new HashMap<String, Entry>();
   
    private CControl control;
   
    private CPerspective perspective;
   
    /**
     * Creates a new factory.
     * @param control the owner of the factory, the factory will add {@link SingleCDockable}
     * to this control
     */
    public CommonSingleDockableFactory( CControl control ){
        this.control = control;
    }
   
    /**
     * Creates a new factory.
     * @param control the owner of the factory, the factory will add {@link SingleCDockable}
     * to this control
     * @param perspective the perspective which is used to load perspective related content
     */
    public CommonSingleDockableFactory( CControl control, CPerspective perspective ){
      this.control = control;
      this.perspective = perspective;
    }
   
    /**
     * Registers a new factory that will load {@link SingleCDockable}s with
     * the unique id <code>id</code>.
     * @param id the unique id of the dockables which <code>factory</code> will create
     * @param factory the new factory
     */
    public void add( String id, SingleCDockableFactory factory ){
      Entry old = singleIdFactories.remove( id );
      if( old != null ){
        factories.remove( old );
      }
     
      Entry entry = new Entry( new PresetFilter<String>( id ), factory );
      factories.add( entry );
      singleIdFactories.put( id, entry );
    }
   
    /**
     * Registers a new factory that will load {@link SingleCDockable} with
     * unique identifiers that are included by <code>ids</code>.
     * @param ids the identifiers that are included
     * @param factory the new factory
     */
    public void add( Filter<String> ids, SingleCDockableFactory factory ){
      factories.add( new Entry( ids, factory ));
    }
   
    /**
     * Removes a factory from this.
     * @param id the name of the factory to remove
     */
    public void remove( String id ){
        Entry entry = singleIdFactories.remove( id );
        if( entry != null ){
          factories.remove( entry );
        }
    }
   
    /**
     * Removes any occurrence of <code>factory</code>.
     * @param factory the factory to remove
     */
    public void remove( SingleCDockableFactory factory ){
      Iterator<Entry> entries = factories.iterator();
      while( entries.hasNext() ){
        Entry next = entries.next();
        if( next.factory == factory ){
          entries.remove();
        }
      }
     
      entries = singleIdFactories.values().iterator();
      while( entries.hasNext() ){
        Entry next = entries.next();
        if( next.factory == factory ){
          entries.remove();
        }
      }
    }
   
    /**
     * Searches the factory which handles <code>id</code>.
     * @param id the name of a factory
     * @return the factory or <code>null</code>
     */
    public SingleCDockableFactory getFactory( String id ){
      Entry entry = singleIdFactories.get( id );
      if( entry != null ){
        return entry.factory;
      }
     
      for( Entry factory : factories ){
        if( factory.filter.includes( id )){
          return factory.factory;
        }
      }
     
      return null;
    }
   
    public String getID() {
        return BACKUP_FACTORY_ID;
    }
   
    /**
     * Gets a list of keys for all factories known to this.
     * @return the list of keys
     */
    public String[] listFactories(){
        Set<String> keys = singleIdFactories.keySet();
        return keys.toArray( new String[ keys.size() ] );
    }
   
    /**
     * Gets the set of keys for all factories known to this.
     * @return the set of keys
     */
    public Set<String> getFactoryIds(){
        return Collections.unmodifiableSet( singleIdFactories.keySet() );
    }
   
    public void estimateLocations( CommonSingleDockableLayout layout, LocationEstimationMap children ){
      // currently not supported
    }

    public CommonSingleDockableLayout getLayout( CommonDockable element, Map<Dockable, Integer> children ) {
        CDockable dockable = element.getDockable();
        if( dockable instanceof SingleCDockable ){
            SingleCDockable single = (SingleCDockable)dockable;
            CommonSingleDockableLayout layout = new CommonSingleDockableLayout();
            layout.setId( single.getUniqueId() );
            layout.setArea( single.getWorkingArea() == null ? null : single.getWorkingArea().getUniqueId() );
            return layout;
        }
        else
            throw new IllegalArgumentException( "A CommonSingleDockableFactory works only with Dockables of type SingleCDockable, but this is not a single dockable: " + element );
    }

    public CommonDockable layout( CommonSingleDockableLayout layout, Map<Integer, Dockable> children, PlaceholderStrategy placeholders ) {
        return layout( layout, placeholders );
    }

    public CommonDockable layout( CommonSingleDockableLayout layout, PlaceholderStrategy placeholders ) {
        SingleCDockableFactory backup = getFactory( layout.getId() );
        if( backup == null )
            return null;
       
        SingleCDockable dockable = backup.createBackup( layout.getId() );
        if( dockable == null )
            return null;
       
        String factoryId = dockable.intern().getFactoryID();
        if( !factoryId.equals( getID() )){
          throw new IllegalArgumentException( "Wrong type of dockable for unique id '" + layout.getId() + "': The backup factory created a dockable which expects a factory with type-id '" + factoryId +
              "',  but the call was done from a factory with type-id '" + getID() + "'" );
        }
       
        control.addDockable( dockable );
        if( layout.isAreaSet()){
          if( layout.getArea() != null ){
            CStation<?> station = control.getStation( layout.getArea() );
            if( station == null ){
              DelayedWorkingAreaSetter setter = new DelayedWorkingAreaSetter( layout.getArea(), dockable, control );
              setter.install();
            }
            else {
              dockable.setWorkingArea( station );
            }
          }
          else{
            dockable.setWorkingArea( null );
          }
        }
        return dockable.intern();
    }
   
    public CommonElementPerspective layoutPerspective( CommonSingleDockableLayout layout, Map<Integer, PerspectiveDockable> children ){
      SingleCDockablePerspective dockable = new SingleCDockablePerspective( layout.getId() );
      if( layout.isAreaSet() && layout.getArea() != null ){
        dockable.setWorkingArea( perspective.getStation( layout.getArea() ));
      }
     
      return dockable.intern();
    }
   
    public void layoutPerspective( CommonElementPerspective perspective, CommonSingleDockableLayout layout, Map<Integer, PerspectiveDockable> children ){
      // can't do anything
    }
   
    public CommonSingleDockableLayout getPerspectiveLayout( CommonElementPerspective element, Map<PerspectiveDockable, Integer> children ){
      SingleCDockablePerspective dockable = (SingleCDockablePerspective)element.getElement();
      CommonSingleDockableLayout layout = new CommonSingleDockableLayout();
      layout.setId( dockable.getUniqueId() );
      layout.setArea( dockable.getWorkingArea() == null ? null : dockable.getWorkingArea().getUniqueId() );
      return layout;
    }

    public CommonSingleDockableLayout read( DataInputStream in, PlaceholderStrategy placeholders ) throws IOException {
        Version version = Version.read( in );
        CommonSingleDockableLayout layout = new CommonSingleDockableLayout();
       
        if( version.equals( Version.VERSION_1_0_4 )){
          layout.setId( in.readUTF() );
        }
        else if( version.equals( Version.VERSION_1_1_0 )){
          layout.setId( in.readUTF() );
          layout.setArea( in.readUTF() );
        }
        else if( version.equals( Version.VERSION_1_1_0a )){
          layout.setId( in.readUTF() );
          if( in.readBoolean() ){
            layout.setArea( in.readUTF() );
          }
          else{
            layout.setArea( null );
          }
        }
        else{
            throw new IOException( "Data from the future - unknown version: " + version );
        }
       
        return layout;
    }

    public CommonSingleDockableLayout read( XElement element, PlaceholderStrategy placeholders ) {
        CommonSingleDockableLayout layout = new CommonSingleDockableLayout();
     
      layout.setId( element.getElement( "id" ).getString() );
     
      XElement xarea = element.getElement( "area" );
      if( xarea != null ){
        String area = element.getString();
        if( "".equals( area )){
          layout.setArea( null );
        }
        else{
          layout.setArea( area );
        }
      }
       
      return layout;
    }

    public void setLayout( CommonDockable element, CommonSingleDockableLayout layout, Map<Integer, Dockable> children, PlaceholderStrategy placeholders ) {
        // can't do anything
    }

    public void setLayout( CommonDockable element, CommonSingleDockableLayout layout, PlaceholderStrategy placeholders ) {
        // can't do anything
    }

    public void write( CommonSingleDockableLayout layout, DataOutputStream out ) throws IOException {
        Version.write( out, Version.VERSION_1_1_0a );
        out.writeUTF( layout.getId() );
       
        String area = layout.getArea();
        if( area == null ){
          out.writeBoolean( false );
        }
        else{
          out.writeBoolean( true );
          out.writeUTF( area );
        }
    }

    public void write( CommonSingleDockableLayout layout, XElement element ) {
        element.addElement( "id" ).setString( layout.getId() );
        XElement xarea = element.addElement( "area" );
        if( layout.getArea() != null ){
          xarea.setString( layout.getArea() );
        }
    }
   
    /**
     * One backup factory of a {@link CommonSingleDockableFactory}
     */
    private static class Entry{
      /** the filter to apply before {@link #factory} can be used */
      public final Filter<String> filter;
      /** the factory represented by this entry */
      public final SingleCDockableFactory factory;
     
      /**
       * Creates a new entry.
       * @param filter the filter to use
       * @param factory the new factory
       */
      public Entry( Filter<String> filter, SingleCDockableFactory factory ){
        if( filter == null ){
          throw new IllegalArgumentException( "filter must not be null" );
        }
        if( factory == null ){
          throw new IllegalArgumentException( "factory must not be null" );
        }
       
        this.filter = filter;
        this.factory = factory;
      }
    }
}
TOP

Related Classes of bibliothek.gui.dock.common.intern.CommonSingleDockableFactory$Entry

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.