1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 import java.awt.*; 25 import java.awt.event.*; 26 27 import com.sun.star.uno.XComponentContext; 28 import com.sun.star.lang.XMultiComponentFactory; 29 import com.sun.star.frame.XComponentLoader; 30 import com.sun.star.uno.UnoRuntime; 31 import com.sun.star.uno.XComponentContext; 32 import com.sun.star.io.IOException; 33 import com.sun.star.connection.XConnector; 34 import com.sun.star.connection.XConnection; 35 36 import com.sun.star.beans.XPropertySet; 37 38 import com.sun.star.lang.XEventListener; 39 import com.sun.star.lang.XComponent; 40 41 import com.sun.star.bridge.XBridgeFactory; 42 import com.sun.star.bridge.XBridge; 43 44 45 public class ConnectionAwareClient extends java.awt.Frame 46 implements ActionListener , com.sun.star.lang.XEventListener 47 { 48 private Button _btnWriter,_btnCalc; 49 private Label _txtLabel; 50 private String _url; 51 52 private XComponentContext _ctx; 53 54 private com.sun.star.frame.XComponentLoader _officeComponentLoader; 55 ConnectionAwareClient( XComponentContext ctx , String url )56 public ConnectionAwareClient( XComponentContext ctx , String url ) 57 { 58 _url = url; 59 _ctx = ctx; 60 61 Panel p1 = new Panel(); 62 _btnWriter = new Button("New writer"); 63 _btnCalc = new Button("New calc"); 64 _txtLabel = new Label( "disconnected" ); 65 66 _btnWriter.addActionListener(this); 67 _btnCalc.addActionListener(this); 68 p1.add( _btnWriter ); 69 p1.add( _btnCalc ); 70 p1.add( _txtLabel ); 71 72 addWindowListener( 73 new WindowAdapter() 74 { 75 public void windowClosing(WindowEvent event) 76 { 77 System.exit(0); 78 } 79 } 80 ); 81 82 add( p1 ); 83 } 84 disposing( com.sun.star.lang.EventObject event )85 public void disposing( com.sun.star.lang.EventObject event ) 86 { 87 // remote bridge has gone down, because the office crashed or was terminated. 88 _officeComponentLoader = null; 89 _txtLabel.setText( "disconnected" ); 90 } 91 actionPerformed( ActionEvent event )92 public void actionPerformed( ActionEvent event ) 93 { 94 try 95 { 96 String sUrl; 97 if( event.getSource() == _btnWriter ) 98 { 99 sUrl = "private:factory/swriter"; 100 } 101 else 102 { 103 sUrl = "private:factory/scalc"; 104 } 105 getComponentLoader().loadComponentFromURL( 106 sUrl, "_blank", 0,new com.sun.star.beans.PropertyValue[0] ); 107 _txtLabel.setText( "connected" ); 108 } 109 catch ( com.sun.star.connection.NoConnectException exc ) 110 { 111 _txtLabel.setText( exc.getMessage() ); 112 } 113 catch ( com.sun.star.uno.Exception exc ) 114 { 115 _txtLabel.setText( exc.getMessage() ); 116 exc.printStackTrace(); 117 throw new java.lang.RuntimeException( exc.getMessage() ); 118 } 119 } 120 121 /** separtates the uno-url into 3 different parts. 122 */ parseUnoUrl( String url )123 protected static String[] parseUnoUrl( String url ) 124 { 125 String [] aRet = new String [3]; 126 127 if( ! url.startsWith( "uno:" ) ) 128 { 129 return null; 130 } 131 132 int semicolon = url.indexOf( ';' ); 133 if( semicolon == -1 ) 134 return null; 135 136 aRet[0] = url.substring( 4 , semicolon ); 137 int nextSemicolon = url.indexOf( ';' , semicolon+1); 138 139 if( semicolon == -1 ) 140 return null; 141 aRet[1] = url.substring( semicolon+1, nextSemicolon ); 142 143 aRet[2] = url.substring( nextSemicolon+1); 144 return aRet; 145 } 146 147 148 getComponentLoader()149 protected com.sun.star.frame.XComponentLoader getComponentLoader() 150 throws com.sun.star.uno.Exception 151 { 152 XComponentLoader officeComponentLoader = _officeComponentLoader; 153 154 if( officeComponentLoader == null ) 155 { 156 // instantiate connector service 157 Object x = _ctx.getServiceManager().createInstanceWithContext( 158 "com.sun.star.connection.Connector", _ctx ); 159 160 XConnector xConnector = (XConnector ) 161 UnoRuntime.queryInterface(XConnector.class, x); 162 163 String a[] = parseUnoUrl( _url ); 164 if( null == a ) 165 { 166 throw new com.sun.star.uno.Exception( "Couldn't parse uno-url "+ _url ); 167 } 168 169 // connect using the connection string part of the uno-url only. 170 XConnection connection = xConnector.connect( a[0] ); 171 172 x = _ctx.getServiceManager().createInstanceWithContext( 173 "com.sun.star.bridge.BridgeFactory", _ctx ); 174 175 XBridgeFactory xBridgeFactory = (XBridgeFactory) UnoRuntime.queryInterface( 176 XBridgeFactory.class , x ); 177 178 // create a nameless bridge with no instance provider 179 // using the middle part of the uno-url 180 XBridge bridge = xBridgeFactory.createBridge( "" , a[1] , connection , null ); 181 182 // query for the XComponent interface and add this as event listener 183 XComponent xComponent = (XComponent) UnoRuntime.queryInterface( 184 XComponent.class, bridge ); 185 xComponent.addEventListener( this ); 186 187 // get the remote instance 188 x = bridge.getInstance( a[2] ); 189 190 // Did the remote server export this object ? 191 if( null == x ) 192 { 193 throw new com.sun.star.uno.Exception( 194 "Server didn't provide an instance for" + a[2], null ); 195 } 196 197 // Query the initial object for its main factory interface 198 XMultiComponentFactory xOfficeMultiComponentFactory = ( XMultiComponentFactory ) 199 UnoRuntime.queryInterface( XMultiComponentFactory.class, x ); 200 201 // retrieve the component context (it's not yet exported from the office) 202 // Query for the XPropertySet interface. 203 XPropertySet xProperySet = ( XPropertySet ) 204 UnoRuntime.queryInterface( XPropertySet.class, xOfficeMultiComponentFactory ); 205 206 // Get the default context from the office server. 207 Object oDefaultContext = 208 xProperySet.getPropertyValue( "DefaultContext" ); 209 210 // Query for the interface XComponentContext. 211 XComponentContext xOfficeComponentContext = 212 ( XComponentContext ) UnoRuntime.queryInterface( 213 XComponentContext.class, oDefaultContext ); 214 215 216 // now create the desktop service 217 // NOTE: use the office component context here ! 218 Object oDesktop = xOfficeMultiComponentFactory.createInstanceWithContext( 219 "com.sun.star.frame.Desktop", xOfficeComponentContext ); 220 221 officeComponentLoader = ( XComponentLoader ) 222 UnoRuntime.queryInterface( XComponentLoader.class, oDesktop ); 223 224 if( officeComponentLoader == null ) 225 { 226 throw new com.sun.star.uno.Exception( 227 "Couldn't instantiate com.sun.star.frame.Desktop" , null ); 228 } 229 _officeComponentLoader = officeComponentLoader; 230 } 231 return officeComponentLoader; 232 } 233 main( String [] args )234 public static void main( String [] args ) throws java.lang.Exception 235 { 236 if( args.length != 1 ) 237 { 238 System.out.println( "usage: ConnectionAwareClient uno-url" ); 239 return; 240 } 241 XComponentContext ctx = 242 com.sun.star.comp.helper.Bootstrap.createInitialComponentContext( null ); 243 244 ConnectionAwareClient connAware = new ConnectionAwareClient( ctx, args[0]); 245 connAware.pack(); 246 connAware.setVisible( true ); 247 } 248 } 249 250