Package bibliothek.gui.dock.common.intern.station

Source Code of bibliothek.gui.dock.common.intern.station.CommonDockStationFactory

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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Map;

import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DockElement;
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.intern.CDockable;
import bibliothek.gui.dock.common.intern.CommonSingleDockableFactory;
import bibliothek.gui.dock.common.perspective.CElementPerspective;
import bibliothek.gui.dock.common.perspective.CStationPerspective;
import bibliothek.gui.dock.common.perspective.CommonDockStationPerspective;
import bibliothek.gui.dock.frontend.FrontendPerspectiveCache;
import bibliothek.gui.dock.layout.DockLayout;
import bibliothek.gui.dock.layout.LocationEstimationMap;
import bibliothek.gui.dock.perspective.PerspectiveDockable;
import bibliothek.gui.dock.perspective.PerspectiveElement;
import bibliothek.gui.dock.station.support.PlaceholderStrategy;
import bibliothek.util.Version;
import bibliothek.util.xml.XElement;
import bibliothek.util.xml.XException;

/**
* A factory that is responsible for storing and loading the layout of the
* {@link CommonDockStation}s. This factory actually forwards the work to
* a real {@link DockFactory} and only stores meta-data (like "was the
* {@link CommonDockStation} as {@link SingleCDockable}?").
* @author Benjamin Sigg
*/
public class CommonDockStationFactory implements DockFactory<CommonDockStation<?, ?>, CommonDockStationPerspective, CommonDockStationLayout>{
  /** The unique identifier of this factory */
  public static final String FACTORY_ID = "CommonDockStationFactory";
 
  /** The control in whose realm this factory is used */
  private CControl control;

  /** The factory used to create new {@link CommonDockStation}s that are also {@link SingleCDockable}s */
  private CommonSingleDockableFactory singleDockableFactory;
 
  /** Factory used to access missing {@link PerspectiveElement}s */
  private FrontendPerspectiveCache cache;
 
  /**
   * Creates a new factory
   * @param control the {@link CControl} in whose realm this factory works, not <code>null</code>
   * @param cache used to create missing {@link PerspectiveElement}s, can be <code>null</code>
   * @param singleDockableFactory the factory used to create new {@link CommonDockStation}s that are also {@link SingleCDockable}s, not <code>null</code>
   */
  public CommonDockStationFactory( CControl control, FrontendPerspectiveCache cache, CommonSingleDockableFactory singleDockableFactory ){
    if( control == null ){
      throw new IllegalArgumentException( "control must not be null" );
    }
    if( singleDockableFactory == null ){
      throw new IllegalArgumentException( "singleDockableFactory must not be null" );
    }
    this.control = control;
    this.cache = cache;
    this.singleDockableFactory = singleDockableFactory;
  }
 
  /**
   * Creates a new {@link CommonDockStation} whose {@link CStation} is also a {@link SingleCDockable} with
   * unique identifier <code>id</code>.
   * @param id the unique identifier of a {@link SingleCDockable}
   * @return the new station or <code>null</code> if <code>id</code> is unknown
   */
  protected CommonDockStation<?, ?> createStation( String id ){
      SingleCDockableFactory factory = singleDockableFactory.getFactory( id );
      if( factory == null ){
        return null;
      }
     
      SingleCDockable dockable = factory.createBackup( id );
      if( dockable == null ){
        return null;
      }
     
        String factoryId = dockable.intern().getFactoryID();
        if( !factoryId.equals( getID() )){
          throw new IllegalArgumentException( "Wrong type of dockable for unique id '" + id + "': The backup factory created a dockable which expects a factory of type '" + factoryId +
              "',  but the call was done from a factory of type '" + getID() + "'" );
        }
       
      CStation<?> station = dockable.asStation();
      if( station == null ){
        System.err.println( "unique identifier '" + id + "' was supposed to be a CStation, but factory created a dockable" );
        return null;
      }
     
      return (CommonDockStation<?, ?>)station.getStation()
  }
 
  /**
   * Register <code>station</code> at the {@link CControl} in whose realm this factory works.
   * @param station the station to register
   * @param root whether to set the root flag or not
   */
  protected void registerStation( CStation<?> station, boolean root ){
    if( control.getStation( station.getUniqueId() ) != station ){
      control.addStation( station, root );
    }
    CDockable dockable = station.asDockable();
    if( dockable != null ){
      if( dockable instanceof SingleCDockable ){
        SingleCDockable single = (SingleCDockable)dockable;
        if( control.getSingleDockable( single.getUniqueId() ) != single ){
          control.addDockable( single );
        }
      }
    }
  }

  public String getID(){
    return FACTORY_ID;
  }
 
  @SuppressWarnings("unchecked")
  public CommonDockStationLayout getLayout( CommonDockStation<?, ?> element, Map<Dockable, Integer> children ){
    String factoryId = element.getConverterID();
    DockFactory<DockElement, ?, ?> factory = (DockFactory<DockElement, ?, ?>)control.intern().getDockFactory( factoryId );
    if( factory == null ){
      return null;
    }
   
    Object layout = factory.getLayout( element, children );
    if( layout == null ){
      return null;
    }
   
    CDockable dockable = element.getStation().asDockable();
    String id = null;
    if( dockable instanceof SingleCDockable ){
      id = ((SingleCDockable)dockable).getUniqueId();
    }
   
    boolean root = control.isRootStation( element.getStation() );
    return new CommonDockStationLayout( id, root, factoryId, new DockLayout<Object>( factoryId, layout ) );
  }

  public CommonDockStation<?, ?> layout( CommonDockStationLayout layout, Map<Integer, Dockable> children, PlaceholderStrategy placeholders ){
    CommonDockStation<?, ?> station = createStation( layout.getId() );
    if( station == null ){
      return null;
    }
   
    registerStation( station.getStation(), layout.isRoot() );
   
    setLayout( station, layout, children, placeholders );
   
    return station;
  }

  public CommonDockStation<?, ?> layout( CommonDockStationLayout layout, PlaceholderStrategy placeholders ){
    return layout( layout, null, placeholders );
  }
 
  @SuppressWarnings("unchecked")
  public void setLayout( CommonDockStation<?, ?> element, CommonDockStationLayout layout, Map<Integer, Dockable> children, PlaceholderStrategy placeholders ){
    String factoryId = element.getConverterID();
    DockFactory<DockElement, ?, Object> factory = (DockFactory<DockElement, ?, Object>)control.intern().getDockFactory( factoryId );
    if( factory == null ){
      return;
    }
   
    layout.updateLayout( factory, placeholders );
    DockLayout<?> data = layout.getLayout();
    if( data == null ){
      return;
    }
   
    if( children == null ){
      factory.setLayout( element, data.getData(), placeholders );
    }
    else{
      factory.setLayout( element, data.getData(), children, placeholders );
    }
  }

  public void setLayout( CommonDockStation<?, ?> element, CommonDockStationLayout layout, PlaceholderStrategy placeholders ){
    setLayout( element, layout, null, placeholders )
  }
 
  @SuppressWarnings("unchecked")
  public void estimateLocations( CommonDockStationLayout layout, LocationEstimationMap children ){
    String factoryId = null;
    if( layout != null ){
      factoryId = layout.getFactoryId();
    }
    if( factoryId == null ){
      return;
    }
    DockFactory<DockElement, ?, Object> factory = (DockFactory<DockElement, ?, Object>)control.intern().getDockFactory( factoryId );
    if( factory == null ){
      return;
    }
    layout.updateLayout( factory, null );
    DockLayout<?> data = layout.getLayout();
    if( data == null ){
      return;
    }
    factory.estimateLocations( data.getData(), children );
  }

  public CommonDockStationPerspective layoutPerspective( CommonDockStationLayout layout, Map<Integer, PerspectiveDockable> children ){
    CommonDockStationPerspective element = null;
    if( cache != null ){
      element = (CommonDockStationPerspective)cache.get( layout.getId(), layout.isRoot() );
    }
    if( element == null ){
      return null;
    }
   
    layoutPerspective( element, layout, children );
    return element;
  }

  @SuppressWarnings("unchecked")
  public void layoutPerspective( CommonDockStationPerspective element, CommonDockStationLayout layout, Map<Integer, PerspectiveDockable> children ){
    CStationPerspective station = element.getElement().asStation();
    station.setRoot( layout.isRoot() );
   
    DockFactory<?, PerspectiveElement, Object> factory = (DockFactory<?, PerspectiveElement, Object>)control.intern().getDockFactory( layout.getFactoryId() );
    if( factory == null ){
      return;
    }
   
    layout.updateLayout( factory, null );
    DockLayout<?> data = layout.getLayout();
    if( data == null ){
      return;
    }
   
    factory.layoutPerspective( element, data.getData(), children );
  }
 
  @SuppressWarnings("unchecked")
  public CommonDockStationLayout getPerspectiveLayout( CommonDockStationPerspective element, Map<PerspectiveDockable, Integer> children ){
    String factoryId = element.getConverterID();
    DockFactory<?, PerspectiveElement, Object> dockFactory = (DockFactory<?, PerspectiveElement, Object>)control.intern().getDockFactory( factoryId );
    DockFactory<?, PerspectiveElement, Object> factory = dockFactory;
    if( factory == null ){
      return null;
    }
    Object data = factory.getPerspectiveLayout( element, children );
    if( data == null ){
      return null;
    }
   
    CElementPerspective celement = element.getElement();
    CStationPerspective station = celement.asStation();
   
    String id = station.getUniqueId();
       
    return new CommonDockStationLayout( id, station.isRoot(), factoryId, new DockLayout<Object>( factoryId, data ) );
  }

  @SuppressWarnings("unchecked")
  public void write( CommonDockStationLayout layout, XElement element ){
    String factoryId = layout.getFactoryId();
    DockFactory<DockElement, ?, Object> factory = (DockFactory<DockElement, ?, Object>)control.intern().getDockFactory( factoryId );
    XElement content = layout.getLayoutXML();
    if( content == null ){
      layout.updateLayout( factory, null );
      DockLayout<?> data = layout.getLayout();
      if( data == null ){
        throw new XException( "data are null, but data were just updated" );
      }
      content = new XElement("content");
      factory.write( data.getData(), content );
    }
   
    String id = layout.getId();
    if( id != null ){
      element.addElement( "id" ).setString( id );
    }
    element.addElement( "root" ).setBoolean( layout.isRoot() );
   
    content.addString( "delegate", factoryId );
    element.addElement( content );
  }
 
  @SuppressWarnings("unchecked")
  public CommonDockStationLayout read( XElement element, PlaceholderStrategy placeholders ){
    String id = null;
    XElement xid = element.getElement( "id" );
    if( xid != null ){
      id = xid.getString();
    }
   
    boolean root = element.getElement( "root" ).getBoolean();
   
    XElement xcontent = element.getElement( "content" );
    if( xcontent == null ){
      throw new XException( "missing content element" );
    }
   
    String factoryId = xcontent.getString( "delegate" );
    DockFactory<DockElement, ?, Object> factory = (DockFactory<DockElement, ?, Object>)control.intern().getDockFactory( factoryId );
    if( factory == null ){
      return new CommonDockStationLayout( id, root, factoryId, xcontent );
    }
    else{
      Object data = factory.read( xcontent, placeholders );
      if( data == null ){
        return null;
      }
     
      return new CommonDockStationLayout( id, root, factoryId, new DockLayout<Object>( factoryId, data ) );
    }
  }

  @SuppressWarnings("unchecked")
  public void write( CommonDockStationLayout layout, DataOutputStream out ) throws IOException{
    String factoryId = layout.getFactoryId();
    DockFactory<DockElement, ?, Object> factory = (DockFactory<DockElement, ?, Object>)control.intern().getDockFactory( factoryId );
    byte[] content = layout.getLayoutBytes();
    if( content == null ){
      layout.updateLayout( factory, null );
      DockLayout<?> data = layout.getLayout();
      if( data == null ){
        throw new IOException( "data are null, but data were just updated" );
      }
      ByteArrayOutputStream bout = new ByteArrayOutputStream();
      factory.write( data.getData(), new DataOutputStream( bout ) );
      content = bout.toByteArray();
    }
    if( content == null ){
      throw new IOException( "unable to write layout, it could not be converted into byte-array format" );
    }
   
    Version.write( out, Version.VERSION_1_1_1 );
   
    String id = layout.getId();
    if( id == null ){
      out.writeBoolean( false );
    }
    else{
      out.writeBoolean( true );
      out.writeUTF( id );
    }
   
    out.writeBoolean( layout.isRoot() );
   
    out.writeUTF( factoryId );
   
    out.writeInt( content.length );
    out.write( content );
  }
 
  @SuppressWarnings("unchecked")
  public CommonDockStationLayout read( DataInputStream in, PlaceholderStrategy placeholders ) throws IOException{
    Version.read( in ).checkCurrent();
   
    String id;
    if( in.readBoolean() ){
      id = in.readUTF();
    }
    else{
      id = null;
    }
   
    boolean root = in.readBoolean();
   
    String factoryId = in.readUTF();
   
    int length = in.readInt();
    byte[] content = new byte[length];
    int offset = 0;
    while( offset < length ){
      int delta = in.read( content, offset, length - offset );
      if( delta == -1 ){
        throw new EOFException();
      }
      offset += delta;
    }
   
    DockFactory<DockElement, ?, Object> factory = (DockFactory<DockElement, ?, Object>)control.intern().getDockFactory( factoryId );
    if( factory == null ){
      return new CommonDockStationLayout( id, root, factoryId, content );
    }
    else{
      Object data = factory.read( new DataInputStream( new ByteArrayInputStream( content ) ), placeholders );
      if( data == null ){
        return null;
      }
      return new CommonDockStationLayout( id, root, factoryId, new DockLayout<Object>( factoryId, data ) );
    }
  }
}
TOP

Related Classes of bibliothek.gui.dock.common.intern.station.CommonDockStationFactory

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.