Package com.sun.star.beans

Source Code of com.sun.star.beans.LocalOfficeConnection$OfficeService

/*************************************************************************
*
*  $RCSfile: LocalOfficeConnection.java,v $
*
*  $Revision: 1.12.2.1 $
*
*  last change: $Author: jsc $ $Date: 2003/02/24 21:09:47 $
*
*  The Contents of this file are made available subject to the terms of
*  either of the following licenses
*
*         - GNU Lesser General Public License Version 2.1
*         - Sun Industry Standards Source License Version 1.1
*
*  Sun Microsystems Inc., October, 2000
*
*  GNU Lesser General Public License Version 2.1
*  =============================================
*  Copyright 2000 by Sun Microsystems, Inc.
*  901 San Antonio Road, Palo Alto, CA 94303, USA
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License version 2.1, as published by the Free Software Foundation.
*
*  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., 59 Temple Place, Suite 330, Boston,
*  MA  02111-1307  USA
*
*
*  Sun Industry Standards Source License Version 1.1
*  =================================================
*  The contents of this file are subject to the Sun Industry Standards
*  Source License Version 1.1 (the "License"); You may not use this file
*  except in compliance with the License. You may obtain a copy of the
*  License at http://www.openoffice.org/license.html.
*
*  Software provided under this License is provided on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
*  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
*  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
*  See the License for the specific provisions governing your rights and
*  obligations concerning the Software.
*
*  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
*  Copyright: 2000 by Sun Microsystems, Inc.
*
*  All Rights Reserved.
*
*  Contributor(s): _______________________________________
*
*
************************************************************************/

package com.sun.star.beans;

import java.awt.Component;
import java.awt.Container;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.Properties;
import java.util.Enumeration;

import com.sun.star.lang.XSingleServiceFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XEventListener;
import com.sun.star.lang.XInitialization;
import com.sun.star.container.XSet;
import com.sun.star.connection.XConnection;
import com.sun.star.bridge.XBridge;
import com.sun.star.bridge.XBridgeFactory;
import com.sun.star.comp.loader.JavaLoader;
import com.sun.star.loader.XImplementationLoader;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.Type;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.Exception;

/**
* This class reprecents a connection to the local office application.
*/
public class LocalOfficeConnection
  implements OfficeConnection
{
  public static final String    OFFICE_APP_NAME    = "soffice";
  public static final String    OFFICE_LIB_NAME    = "officebean";
  public static final String    OFFICE_PROP_FILE  = "officebean.properties";
  public static final String    OFFICE_CONN_PROT  = "urp";
  public static final String    OFFICE_BRIDGE_NAME  = "officebridge";
  public static final String    OFFICE_ID_SUFFIX  = "_Office";
 
  private String          mURL;
  private ContainerFactory    mContainerFactory;

  private XMultiServiceFactory  mLocalServiceFactory;
  private String          mProgramPath;
  private String          mLibPath;
  private String          mPipeName;
  private XConnection        mConnection;
  private XBridge          mBridge;
  private XComponentContext    mComponentContext;

  private List  mComponents  = new Vector();

  /**
   * Static constructor.
   *
   * Reads the officebean properties file form use's home directory.
   */
  static {
    try {   
      String  name;
      name  = (System.getProperty("os.name").startsWith("Windows"))?
        OFFICE_PROP_FILE: ("." + OFFICE_PROP_FILE);
      File file = new File(System.getProperty("user.home"), name);

      if (file.canRead()) {
        Properties properties = new Properties();
        properties.load(new FileInputStream(file));

        Enumeration  e  = properties.propertyNames();
        while (e.hasMoreElements()) {
          name = (String)e.nextElement();
          if (name.startsWith("com.sun.star.beans.") &&
              (System.getProperty(name) == null))
            System.setProperty(name, properties.getProperty(name));
        }
      }
    } catch (IOException e) {
    }
  }
   
  /**
   * Constructor.
   * Sets up paths to the office application and native libraries if
   * values are available in <code>OFFICE_PROP_FILE</code> in the user
   * home directory.<br />
   * "com.sun.star.beans.path" - the office application directory;<br/>
   * "com.sun.star.beans.libpath" - native libraries directory.
   */
  public LocalOfficeConnection()
  {
    mProgramPath  = System.getProperty("com.sun.star.beans.path");
    mLibPath    = System.getProperty("com.sun.star.beans.libpath");
  }

  /**
   * Sets a connection URL.
   * This implementation accepts a UNO URL with following format:<br />
   * <pre>
   * url    := uno:localoffice[,&lt;params&gt;];urp;StarOffice.NamingService
   * params := &lt;path&gt;[,&lt;pipe&gt;]
   * path   := path=&lt;pathv&gt;
   * pipe   := pipe=&lt;pipev&gt;
   * pathv  := platform_specific_path_to_the_local_office_distribution
   * pipev  := local_office_connection_pipe_name
   * </pre>
   *
   * @param url This is UNO URL which discribes the type of a connection.
   */
  public void setUnoUrl(String url)
    throws java.net.MalformedURLException
  {
    mURL  = null;
    parseUnoUrl(url);
    mURL  = url;
  }

  /**
   * Sets an AWT container catory.
   *
   * @param containerFactory This is a application provided AWT container
   *  factory.
   */
  public void setContainerFactory(ContainerFactory containerFactory)
  {
    mContainerFactory  = containerFactory;
  }

  /**
   * Retrives the UNO component context.
   * Establishes a connection if necessary and initialises the 
   * UNO service manager if it has not already been initialised.
   * This method can return <code>null</code> if it fails to connect
   * to the office application.
   *
   * @return The office UNO component context.
   */
  public XComponentContext getComponentContext()
  {
    if (mComponentContext == null)
      connect();
    return mComponentContext;
  }

  /**
   * Creates an office window.
   * The window is either a sub-class of java.awt.Canvas (local) or
   * java.awt.Container (RVP).
   *
   * @param container This is an AWT container.
   * @return The office window instance.
   */
  public OfficeWindow createOfficeWindow(Container container)
  {
    return new LocalOfficeWindow(this);
  }

  /**
   * Closes the connection.
   */
  public void dispose()
  {
    Iterator  itr  = mComponents.iterator();
    while (itr.hasNext() == true) {
      ((XEventListener)itr.next()).disposing(null);
    }
    mComponents.clear();
    // Close the connection
    if (mBridge != null) {
      XComponent  comp  = (XComponent)UnoRuntime.queryInterface(
        XComponent.class, mBridge);
      comp.dispose();
      mComponentContext  = null;
      mBridge        = null;
      mConnection      = null;
    }
  }

  /**
   * Adds an event listener to the object.
   *
   * @param listener is a listener object.
   */
  public void addEventListener(XEventListener listener)
  {
    mComponents.add(listener);
  }

  /**
   * Removes an event listener from the listener list.
   *
   * @param listener is a listener object.
   */
  public void removeEventListener(XEventListener listener)
  {
    mComponents.remove(listener);
  }

  /**
   * Establishes the connection to the office.
   */
  private void connect()
  {
    try {
      buildBridge();
    } catch (com.sun.star.uno.Exception exp) {
      mConnection  = null;
    }
    // Return if the bridge has not been built.
    if (mBridge == null)
      return;
    XMultiServiceFactory  factory  = null;
    try {
      // Get the component context.
      Object  object  = null;
      object  = mBridge.getInstance("StarOffice.ComponentContext");
      mComponentContext  = (XComponentContext)UnoRuntime.queryInterface(
        XComponentContext.class, object);
      if ((mComponentContext == null) ||
        (mComponentContext.getServiceManager() == null))
      {
        // We have original StarOffice 6.0 so do it again.
        mComponentContext  = null;
        object  = mBridge.getInstance("StarOffice.ServiceManager");
        factory  = (XMultiServiceFactory)UnoRuntime.queryInterface(
          XMultiServiceFactory.class, object);
        XPropertySet  props  = (XPropertySet)UnoRuntime.queryInterface(
          XPropertySet.class, object);
        mComponentContext = (XComponentContext)AnyConverter.toObject(
          new Type(XComponentContext.class),
          props.getPropertyValue("DefaultContext"));
      }
    } catch (java.lang.Exception exp) {
      // Unsuccesful connection clean up.
      if (mBridge != null) {
        XComponent  comp;
        if (factory != null) {
          // Dispose the service manager if it has been created.
          comp  = (XComponent)UnoRuntime.queryInterface(
            XComponent.class, factory);
          comp.dispose();
          factory  = null;
        }
        // Dispose the bridge.
        comp  = (XComponent)UnoRuntime.queryInterface(
          XComponent.class, mBridge);
        comp.dispose();
        mBridge        = null;
        // Release the connection and the component context.
        mComponentContext  = null;
        mConnection      = null;
      }
    }
  }

  /**
   * Builds new UNO bridge to the office.
   */
  private void buildBridge()
    throws com.sun.star.uno.Exception
  {
    if (mBridge != null)
      return;
    if (mConnection == null)
      buildConnection();
    Object  object  = mLocalServiceFactory.createInstance(
      "com.sun.star.bridge.BridgeFactory");
    XBridgeFactory  bridgeFactory;
    bridgeFactory  = (XBridgeFactory)UnoRuntime.queryInterface(
      XBridgeFactory.class, object);
    mBridge  = bridgeFactory.createBridge(
      OFFICE_BRIDGE_NAME, OFFICE_CONN_PROT, mConnection, null);
  }

  /**
   * Builds new URP connection to the office.
   */
  private void buildConnection()
    throws com.sun.star.uno.Exception
  {
    if (mLocalServiceFactory == null)
      buildEnvironment();
    NativeConnection  connection  = new NativeConnection();
    connection.connect(new OfficeService());
    mConnection  = connection;
  }

  /**
   * Builds UNO runtime environment.
   */
  private void buildEnvironment()
    throws com.sun.star.uno.Exception
  {
    loadNativeLibrary();

    Object  object  = new JavaLoader();

    XImplementationLoader implLoader;
    implLoader  = (XImplementationLoader)UnoRuntime.queryInterface(
      XImplementationLoader.class, object);

    object  = implLoader.activate(
      "com.sun.star.comp.servicemanager.ServiceManager", null, null, null);

    // Ensure that we have got a factory
    XSingleServiceFactory  managerFact;
    managerFact  = (XSingleServiceFactory)UnoRuntime.queryInterface(
      XSingleServiceFactory.class, object);

    // Create an instance of the ServiceManager
    XMultiServiceFactory  serviceMgr;
    serviceMgr  = (XMultiServiceFactory)UnoRuntime.queryInterface(
      XMultiServiceFactory.class, managerFact.createInstance());

    // Set the ServiceManager at the JavaLoader with the XInitialization
    XInitialization      init;
    init  = (XInitialization)UnoRuntime.queryInterface(
      XInitialization.class, implLoader);

    Object[]  initargs  = { serviceMgr };  
    init.initialize(initargs);

    // Use the XSet interface at the ServiceManager to add the factory of
    // the loader
    XSet  serviceMgrXSet  = (XSet)UnoRuntime.queryInterface(
      XSet.class, serviceMgr);

    XSingleServiceFactory  singleServiceFact;
    // Add the factory of the loader
    singleServiceFact  = (XSingleServiceFactory)UnoRuntime.queryInterface(
      XSingleServiceFactory.class,
      implLoader.activate(
        "com.sun.star.comp.loader.JavaLoader", null, null, null));
    serviceMgrXSet.insert(singleServiceFact);
               
    // Add the service manager
    serviceMgrXSet.insert(managerFact);

    // Add the factory of the URLResolver       
    singleServiceFact  = (XSingleServiceFactory)UnoRuntime.queryInterface(
      XSingleServiceFactory.class,
      implLoader.activate(
        "com.sun.star.comp.urlresolver.UrlResolver", null, null, null));
    serviceMgrXSet.insert(singleServiceFact);

    // Add the bridgefactory
    singleServiceFact  = (XSingleServiceFactory)UnoRuntime.queryInterface(
      XSingleServiceFactory.class,
      implLoader.activate(
        "com.sun.star.comp.bridgefactory.BridgeFactory", null, null, null));
    serviceMgrXSet.insert(singleServiceFact);

    // Ufff ... that's all
    mLocalServiceFactory = serviceMgr;
  }

  /**
   * Loads native libraries.
   */
  private void loadNativeLibrary()
  {
    System.loadLibrary(OFFICE_LIB_NAME);
  }

  /**
   * Retrives a path to the office program folder.
   *
   * @return The path to the office program folder.
   */
  private String getProgramPath()
  {
    if (mProgramPath == null) {
      String  path  = null;
      String  name  = System.getProperty("os.name");
      if (("SunOS".equals(name)) || ("Linux".equals(name))) {
        path  = System.getProperty("user.home");
        path  += "/staroffice6.0";
      } else if (name.startsWith("Windows")) {
        path  = "c:\\Program Files\\StarOffice6.0\\program";
      } else
        return null// unknown OS!
      // Check the directory
      if ((new File(path)).isDirectory() == true)
        mProgramPath  = path;
      else
        mProgramPath  = ""// default path
    }
    return mProgramPath;
  }

  /**
   * Retrives a path to the native libraries folder.
   * This method depends on ODK directory layout. It expects the root ODK
   * directory contains 'classes' directory, where <code>OFFICE_LIB_NAME</code>
   * jar file is located, and OS specific directory for native libraries.
   *
   * @return The path to the native libraries folder.
   */
  private String getLibPath()
  {
    if (mLibPath == null) {
      String  fsep  = System.getProperty("file.separator");
      Class  info  = getClass();
      String  name  = new String(
        '/' + info.getName().replace('.', '/') + ".class");
      String  path  = info.getResource(name).getFile();
      // Get program directory path
      int  idx  = path.indexOf(
        fsep + "classes" + fsep + OFFICE_LIB_NAME + ".jar");
      if (idx > 0) {
        path  = path.substring(0, idx);
        // Get ODK directory absolute path
        idx    = path.indexOf(fsep);
        path  = path.substring(idx);
        // Add OS specific portion of path
        name  = System.getProperty("os.name");
        if ("SunOS".equals(name))
          path  += "/solsparc/lib";
        else if ("Linux".equals(name))
          path  += "/linux/lib";
        else if (name.startsWith("Windows"))
          path  += fsep + "windows" + fsep + "bin";
        else
          return null// unknown OS!
        // Check the directory
        if ((new File(path)).isDirectory() == true)
          mLibPath  = path;
      }
    }
    return mLibPath;
  }

  /**
   * Parses a connection URL.
   * This method accepts a UNO URL with following format:<br />
   * <pre>
   * url    := uno:localoffice[,&lt;params&gt;];urp;StarOffice.NamingService
   * params := &lt;path&gt;[,&lt;pipe&gt;]
   * path   := path=&lt;pathv&gt;
   * pipe   := pipe=&lt;pipev&gt;
   * pathv  := platform_specific_path_to_the_local_office_distribution
   * pipev  := local_office_connection_pipe_name
   * </pre>
   *
   * @param url This is UNO URL which describes the type of a connection.
   * @exception java.net.MalformedURLException when inappropreate URL was
   *  provided.
   */
  private void parseUnoUrl(String url)
    throws java.net.MalformedURLException
  {
    String  prefix  = "uno:localoffice";
    if (url.startsWith(prefix) == false)
      throw new java.net.MalformedURLException(
        "Invalid UNO connection URL.");
    // Extruct parameters.
    int  idx  = url.indexOf(";urp;StarOffice.NamingService");
    if (idx < 0)
      throw new java.net.MalformedURLException(
        "Invalid UNO connection URL.");
    String  params  = url.substring(prefix.length(), idx + 1);
    // Parse parameters.
    String  name  = null;
    String  path  = null;
    String  pipe  = null;
    char  ch;
    int    state  = 0;
    StringBuffer  buffer  = new StringBuffer();
    for(idx = 0; idx < params.length(); idx += 1) {
      ch  = params.charAt(idx);
      switch (state) {
      case 0// initial state
        switch(ch) {
        case ',':
          buffer.delete(0, buffer.length());
          state  = 1;
          break;

        case ';':
          state  = 7;
          break;

        default:
          buffer.delete(0, buffer.length());
          buffer.append(ch);
          state  = 1;
          break;
        }
        break;

      case 1// parameter name
        switch(ch) {
        case ' ':
        case '=':
          name  = buffer.toString();
          state  = (ch == ' ')? 2: 3;
          break;

        case ',':
        case ';':
          state  = -6;      // error: invalid name
          break;

        default:
          buffer.append(ch);
          break;
        }
        break;

      case 2// equal between the name and the value
        switch(ch) {
        case '=':
          state  = 3;
          break;

        case ' ':
          break;

        default:
          state  = -1;      // error: missing '='
          break;
        }
        break;

      case 3// value leading spaces
        switch(ch) {
        case ' ':
          break;

        default:
          buffer.delete(0, buffer.length());
          buffer.append(ch);
          state  = 4;
          break;
        }
        break;

      case 4// value
        switch(ch) {
        case ' ':
        case ',':
        case ';':
          idx   -= 1;      // put back the last read character
          state  = 5;
          if (name.equals("path")) {
            if (path == null)
              path  = buffer.toString();
            else
              state  = -3// error: more then one 'path'
          } else if (name.equals("pipe")) {
            if (pipe == null)
              pipe  = buffer.toString();
            else
              state  = -4// error: more then one 'pipe'
          } else
            state  = -2;    // error: unknown parameter
          buffer.delete(0, buffer.length());
          break;

        default:
          buffer.append(ch);
          break;
        }
        break;

      case 5// a delimeter after the value
        switch(ch) {
        case ' ':
          break;

        case ',':
          state  = 6;
          break;

        case ';':
          state  = 7;
          break;

        default:
          state  = -5;      // error: ' ' inside the value
          break;
        }
        break;

      case 6// leading spaces before next parameter name
        switch(ch) {
        case ' ':
          break;

        default:
          buffer.delete(0, buffer.length());
          buffer.append(ch);
          state  = 1;
          break;
        }
        break;

      default:
        throw new java.net.MalformedURLException(
          "Invalid UNO connection URL.");
      }
    }
    if (state != 7)
      throw new java.net.MalformedURLException(
        "Invalid UNO connection URL.");
    // Set up the connection parameters.
    if (path != null)
      mProgramPath  = path;
    if (pipe != null)
      mPipeName    = pipe;
  }

  /**
   * @para This is an implementation of the native office service.
   */
  private class OfficeService
    implements NativeService
  {
    private Process  mProcess;

    /**
     * Retrive the office service identifier.
     *
     * @return The identifier of the office service.
     */
    public String getIdentifier()
    {
      return (mPipeName == null)?
        (System.getProperty("user.name") + OFFICE_ID_SUFFIX):
        mPipeName;
    }

    /**
     * Starts the office process.
     */
    public void startupService()
      throws java.io.IOException
    {
      String[]  cmdArray  = new String[3];
      cmdArray[0= (new File(getProgramPath(), OFFICE_APP_NAME)).getPath();
      cmdArray[1= "-invisible";
      cmdArray[2= "-accept=pipe,name=" + getIdentifier() + ";" +
        OFFICE_CONN_PROT + ";StarOffice.NamingService";
      mProcess  = Runtime.getRuntime().exec(cmdArray);
    }

    /**
     * Retrives the ammount of time to wait for the startup.
     *
     * @return The ammount of time to wait in seconds(?).
     */
    public int getStartupTime()
    {
      return 60;
    }
  }
}
TOP

Related Classes of com.sun.star.beans.LocalOfficeConnection$OfficeService

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.