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