Package

Source Code of BasicOfficeBean$CommandConveyor

/*************************************************************************
*
*  $RCSfile: BasicOfficeBean.java,v $
*
*  $Revision: 1.4 $
*
*  last change: $Author: hr $ $Date: 2003/06/30 15:29:18 $
*
*  The Contents of this file are made available subject to the terms of
*  the BSD license.
*  Copyright (c) 2003 by Sun Microsystems, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*  1. Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*  2. Redistributions in binary form must reproduce the above copyright
*     notice, this list of conditions and the following disclaimer in the
*     documentation and/or other materials provided with the distribution.
*  3. Neither the name of Sun Microsystems, Inc. nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
*  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
*  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
*  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*    
*************************************************************************/

import java.awt.Component;
import java.awt.Container;
import java.awt.Canvas;
import java.awt.Window;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.List;
import java.util.LinkedList;

import com.sun.star.lang.XComponent;
import com.sun.star.lang.XEventListener;
import com.sun.star.lang.EventObject;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.DisposedException;
import com.sun.star.awt.XWindow;
import com.sun.star.awt.XWindowPeer;
import com.sun.star.awt.InvalidateStyle;
import com.sun.star.frame.XController;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XFrame;
import com.sun.star.frame.XFrames;
import com.sun.star.frame.XFramesSupplier;
import com.sun.star.frame.XModel;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDispatchProvider;
import com.sun.star.frame.XSynchronousFrameLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.frame.FrameActionEvent;
import com.sun.star.frame.FrameAction;
import com.sun.star.frame.FrameSearchFlag;
import com.sun.star.document.XTypeDetection;
import com.sun.star.document.MacroExecMode;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.PropertyState;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.OfficeConnection;
import com.sun.star.beans.OfficeWindow;
import com.sun.star.beans.LocalOfficeWindow;
import com.sun.star.util.CloseVetoException;
import com.sun.star.util.XCloseable;
import com.sun.star.util.XModifiable;
import com.sun.star.util.XURLTransformer;
import com.sun.star.uno.UnoRuntime;

/**
* This class provides a basic functionality of the office bean.
* The application developer can subclass from this class in order
* to provide application specific methods.
*/
public class BasicOfficeBean
  extends Container
{
  private transient OfficeConnection    mConnection;
  private transient OfficeWindow      mWindow;
  private transient CommandConveyor    mCommandConveyor;

  protected String        mDocumentURL;

  protected transient XMultiServiceFactory  mServiceFactory;
  protected transient Object      mDesktop;
  protected transient XFrame      mFrame;
  protected transient XModifiable      mModifiable;

  // slot command execution environment
  protected transient XDispatchProvider    mDispatcher;
  protected transient XURLTransformer    mURLTransformer;
  protected transient XTypeDetection    mTypeDetector;

  /**
   * Constructor.
   *
   * This constructor sets default layout manager (BorderLayout)
   * and creates the command execution conveyor. It also sets the
   * default appearance of the bean.
   */
   public BasicOfficeBean()
   {
     setLayout(new BorderLayout());
     mCommandConveyor  = new CommandConveyor();
     mCommandConveyor.start();
     add(new PlaceHolder());
   }

  /**
   * Sets the office connection object.
   * A subclass can provide own implementation of this method
   * in order to set up the ContainerFactory on the connection
   * object, but it MUST chain with this method implementation.
   *
   * @param connection The connection object.
   */
  public synchronized void setOfficeConnection(OfficeConnection connection)
    throws java.lang.IllegalStateException
  {
    if (mWindow != null)
      throw new java.lang.IllegalStateException(
        "The connection is still open.");
    mConnection  = connection;
    mConnection.addEventListener(new ConnectionListener());
  }

  /**
   * Determines wether document was loaded or not.
   *
   * @return <code>true</code> if a document has been loaded.
   */
  public boolean isDocumentLoaded()
  {
    return (mDocumentURL != null);
  }

  /**
   * Loads a document referenced by a URL.
   *
   * @param url The document's URL string.
   * @exception java.io.IOException if the document loading process has
   *  failed.
   */
  public synchronized void load(String url)
    throws java.io.IOException
  {
    try {
      if (mWindow == null)
        openConnection();

      // Determine the document URL.
      if (url.equals(""))
        url = getDefaultDocumentURL();

      // get XComponentLoader (<= 6.0 => global, >= 6.1 => from frame)
      XComponentLoader xLoader = (XComponentLoader) UnoRuntime.queryInterface(
          XComponentLoader.class, mFrame );
      if ( xLoader == null )
      {
        xLoader = (XComponentLoader)UnoRuntime.queryInterface(
            XComponentLoader.class, mDesktop );
      }

      // Avoid Dialog 'Document changed' while reloading
      boolean bWasModified = isModified();
      XController xOldController = null;
      if ( mFrame != null && mFrame.getController() != null )
        xOldController = mFrame.getController();
      try {
        if ( mFrame != null && xOldController != null )
          xOldController.suspend(true);
        setModified(false);
      } catch (java.lang.IllegalStateException exp) {
      }

      // load the document.
      PropertyValue aArgs[] = new PropertyValue[1];
      aArgs[0] = new PropertyValue();
      aArgs[0].Name = "MacroExecutionMode";
      aArgs[0].Handle = -1;
      aArgs[0].Value = new Short( MacroExecMode.USE_CONFIG );
      XComponent xComponent = xLoader.loadComponentFromURL( url,
        mFrame.getName(), FrameSearchFlag.ALL, aArgs );

      // nothing loaded?
      if ( xComponent == null )
      {
        // reactivate old document
        if ( mFrame != null && mFrame.getController() != null )
          mFrame.getController().suspend(false);
        setModified(true);

        // throw exception
        throw new java.io.IOException(
          "Can not load a document: \"" + url + "\"");
      }
      mDocumentURL = url;

      // Get document's XModifiable interface if any.
      mModifiable = (XModifiable)UnoRuntime.queryInterface(
        XModifiable.class, xComponent );

      // show window (just to test bean creation without system window)
      setVisible(true);
      ((LocalOfficeWindow)mWindow).setVisible(true);

      // Find top most parent and force it to validate.
      Container  parent  = this;
      while(parent.getParent() != null)
        parent  = parent.getParent();
      ((Window)parent).validate();

    } catch (com.sun.star.uno.Exception exp) {
      throw new java.io.IOException(exp.getMessage());
    }
  }

  /**
   * Saves the document.
   */
  public void save()
    throws java.io.IOException
  {
    if (isDocumentLoaded() == false)
      throw new java.io.IOException("The document has not been loaded.");
//    else if (mDocumentURL.startsWith("private:") == true)
//      throw new java.io.IOException("The document URL has not been defined.");
    XStorable  storable  = (XStorable)UnoRuntime.queryInterface(
      XStorable.class, mFrame.getController().getModel());
    try {
      storable.store();
    } catch (com.sun.star.io.IOException exp) {
      throw new java.io.IOException(exp.getMessage());
    }
  }

  /**
   * Saves the document.
   *
   * @param url The location where the document should be stored.
   */
  public void save(String url)
    throws java.io.IOException
  {
    // The implementation of this method MUST replace
    // the document URL with new value on succesful save.

    throw new java.lang.UnsupportedOperationException(
      "There is no implementation for this operation.");
  }

  /**
   * Queues an office command for asynchronous execution.
   *
   * @param command The office command for asynchronous execution.
   */
  public void queue(OfficeCommand command)
  {
    if (command == null)
      throw new java.lang.IllegalArgumentException(
        "The command may not be null.");
    mCommandConveyor.queue(command);
  }

  /**
   * Retrives a URL of the default office document.
   *
   * This method can be overriden by a subclass in order to customize
   * the default document URL.
   *
   * @return The URL of the default document.
   */
  public String getDefaultDocumentURL()
  {
    return null;
  }

  /**
   * Retrives an office document URL.
   *
   * @return The URL of the office document.
   */
  public String getDocumentURL()
  {
    return mDocumentURL;
  }

  /**
   * Determines is the office document modifiable.
   *
   * @return <code>true</code> if the document is modifiable.
   */
  public boolean isModifiable()
  {
    return (mModifiable != null);
  }

  /**
   * Sets the office document modification state.
   *
   * @param state The new state of document modification.
   * @exception java.lang.IllegalStateException if the documnent can not
   *  accept the new modification state.
   */
  public void setModified(boolean state)
    throws java.lang.IllegalStateException
  {
    if (isModifiable() == false) {
      throw new java.lang.IllegalStateException(
        "The document \"" + mDocumentURL + "\" is not modifiable.");
    }
    try {
      mModifiable.setModified(state);
    } catch (com.sun.star.beans.PropertyVetoException exp) {
      throw new java.lang.IllegalStateException(exp.getMessage());
    }
  }

  /**
   * Retrives the office document modification state.
   *
   * @return The document modification state.
   */
  public boolean isModified()
  {
    return (isModifiable() != false)? mModifiable.isModified(): false;
  }

  /**
   * Opens the connection.
   */
  public synchronized void openConnection()
    throws com.sun.star.uno.Exception
  {
    if (mWindow != null)
      return;

    // Establish the connection by request of the ServiceFactory.
    XMultiComponentFactory  compfactory;
    compfactory  = mConnection.getComponentContext().getServiceManager();
    mServiceFactory  = (XMultiServiceFactory)UnoRuntime.queryInterface(
      XMultiServiceFactory.class, compfactory);

    // remove existing child windows
    removeAll();

    // make initially invisible (just to test bean creation without system window)
    setVisible(false);

    // Create the OfficeWindow.
    mWindow  = mConnection.createOfficeWindow(this);
    add(mWindow.getAWTComponent());

    // Create the office document frame and initialize the bean.
    initialize();
  }

  /**
   * Closes the connection.
   */
  public synchronized void closeConnection()
  {
    mConnection.dispose();
  }

  /**
   * Recieves notification of the connection closed event.
   *
   * If a subclass wants to be notified on connection closed event it 
   * should add a listener to the connection object.
   */
  private synchronized void connectionClosed()
  {
    if (mWindow != null)
    {

      // close the frame
      try
      {
        XCloseable xCloseable = (XCloseable)UnoRuntime.queryInterface(
          XCloseable.class, mFrame);
        xCloseable.close(true);
      }
      catch ( DisposedException aExc )
      {
        // add your error handling code here
      }
      catch ( CloseVetoException aExc )
      {
        // add your error handling code here
      }

      // Clean up
      mFrame = null;
      mModifiable = null;
      mDispatcher = null;
      mTypeDetector = null;
      mURLTransformer = null;
      mServiceFactory = null;
      remove((Component)mWindow);
      mWindow = null;
    }
  }

  /**
   * This class is a connection life-cycle event listener.
   */
  private class ConnectionListener
    implements XEventListener
  {
    /**
     * Receives a notification about the connection has been closed.
     *
     * @param source The event object.
     */
    public void disposing(EventObject source)
    {
      connectionClosed();
    }
  }

  /**
   * Office command execution conveyor.
   */
  private class CommandConveyor
    extends Thread
  {
    private final List  mQueue  = new LinkedList();

    /**
     * Appends a command to the tail of the queue.
     *
     * @param command The office command to add to the queue.
     */
    public void queue(OfficeCommand command)
    {
      synchronized (mQueue) {
        mQueue.add(command);
        mQueue.notify();
      }
    }

    /**
     * Executes commands from the queue.
     */
    public void run()
    {
      OfficeCommand  command;
      while (true) {
        try {
          synchronized (mQueue) {
            if (mQueue.isEmpty() == true) {
              mQueue.wait();
            }
            command  = (OfficeCommand)mQueue.remove(0);
          }
          command.execute(BasicOfficeBean.this);
        } catch (java.lang.InterruptedException exp) {
          // Wait has been interrupted.
          // Do nothing, but do not execute a command which
          // does not exist.
        }
      }
    }
  }

  /**
   * Initializes the bean.
   *
   * @exception com.sun.star.uno.Exception if the frame has not been
   *  created or the slot command execution environment initialization
   *  has failed.
   */
  private void initialize()
    throws com.sun.star.uno.Exception
  {
    Object  object;

    // Create the document frame from UNO window. (<= 6.0 => Task, >= 6.1 => Frame)
    XWindow  window  = (XWindow) UnoRuntime.queryInterface(
      XWindow.class, mWindow.getUNOWindowPeer());
    object  = mServiceFactory.createInstance( "com.sun.star.frame.Task");
    if ( object == null )
      object  = mServiceFactory.createInstance( "com.sun.star.frame.Frame");
    mFrame = (XFrame)UnoRuntime.queryInterface( XFrame.class, object );
    mFrame.initialize(window);
    mFrame.setName( mFrame.toString() );
    mDesktop = mServiceFactory.createInstance( "com.sun.star.frame.Desktop");
    XFrames xFrames = ( (XFramesSupplier)UnoRuntime.queryInterface(
        XFramesSupplier.class, mDesktop ) ).getFrames();
    xFrames.append( mFrame );

    // Initializes the slot command execution environment.
    object  = mServiceFactory.createInstance( "com.sun.star.util.URLTransformer");
    mURLTransformer  = (XURLTransformer)UnoRuntime.queryInterface(
      XURLTransformer.class, object);

    object  = mServiceFactory.createInstance(
      "com.sun.star.document.TypeDetection");
    mTypeDetector  = (XTypeDetection)UnoRuntime.queryInterface(
      XTypeDetection.class, object);

    mDispatcher  = (XDispatchProvider)UnoRuntime.queryInterface(
      XDispatchProvider.class, mFrame);
  }

  /**
   * Frees up resources.
   */
  protected void finalize()
    throws Throwable
  {
    super.finalize();
    if (mConnection != null)
      mConnection.dispose();
  }

  /**
   * Default appearance of the bean.
   */
  private class PlaceHolder
    extends Canvas
  {
    public void paint(Graphics g)
    {
      g.setColor(Color.white);
      Rectangle  rect  = getBounds();
      g.fillRect(rect.x, rect.y, rect.width, rect.height);
      g.setColor(new Color(0x666699));
      rect.setBounds(rect.x + 1, rect.y + 1,
        rect.width - 3, rect.height - 3);
      g.drawRect(rect.x, rect.y, rect.width, rect.height);
      rect.setBounds(rect.x + 2, rect.y + 2,
        rect.width - 4, rect.height - 4);
      g.drawRect(rect.x, rect.y, rect.width, rect.height);
      g.drawString(BasicOfficeBean.this.getClass().getName(),
        rect.x + 10, rect.y + 15);
    }
  }
}
TOP

Related Classes of BasicOfficeBean$CommandConveyor

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.