1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package com.sun.star.lib;
29 
30 import com.sun.star.bridge.XBridge;
31 import com.sun.star.bridge.XBridgeFactory;
32 import com.sun.star.bridge.XInstanceProvider;
33 import com.sun.star.comp.helper.Bootstrap;
34 import com.sun.star.connection.Acceptor;
35 import com.sun.star.connection.Connector;
36 import com.sun.star.connection.XAcceptor;
37 import com.sun.star.connection.XConnection;
38 import com.sun.star.connection.XConnector;
39 import com.sun.star.uno.UnoRuntime;
40 import com.sun.star.uno.XComponentContext;
41 import java.io.BufferedReader;
42 import java.io.InputStream;
43 import java.io.InputStreamReader;
44 import java.io.PrintStream;
45 
46 public final class TestBed {
47     public boolean execute(XInstanceProvider provider, boolean waitForServer,
48                            Class client, long wait) throws Exception {
49         // assert client.isAssignableFrom(client) && wait >= 0;
50         synchronized (lock) {
51             server = new Server(provider);
52             server.start();
53             server.waitAccepting();
54         }
55         Process p = Runtime.getRuntime().exec(new String[] {
56             "java", "-classpath", System.getProperty("java.class.path"),
57 /*
58             "-Xdebug",
59             "-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n",
60 */
61             client.getName() });
62         pipe(p.getInputStream(), System.out, "CO> ");
63         pipe(p.getErrorStream(), System.err, "CE> ");
64         boolean clientDone = false;
65         if (wait <= 0) {
66             clientDone = p.waitFor() == CLIENT_DONE;
67         } else {
68             try {
69                 Thread.sleep(wait);
70             } catch (InterruptedException e) {
71                 p.destroy();
72                 throw e;
73             }
74             try {
75                 clientDone = p.exitValue() == CLIENT_DONE;
76             } catch (IllegalThreadStateException e) {
77                 p.destroy();
78             }
79         }
80         boolean success = clientDone;
81         if (waitForServer) {
82             success &= server.waitDone();
83         }
84         return success;
85     }
86 
87     public void serverDone(boolean success) {
88         synchronized (lock) {
89             server.done(success);
90         }
91     }
92 
93     private void pipe(final InputStream in, final PrintStream out,
94                       final String prefix) {
95         new Thread("Pipe: " + prefix) {
96             public void run() {
97                 BufferedReader r
98                     = new BufferedReader(new InputStreamReader(in));
99                 try {
100                     for (;;) {
101                         String s = r.readLine();
102                         if (s == null) {
103                             break;
104                         }
105                         out.println(prefix + s);
106                     }
107                 } catch (java.io.IOException e) {
108                     e.printStackTrace(System.err);
109                 }
110             }
111         }.start();
112     }
113 
114     public static abstract class Client {
115         protected abstract boolean run(XComponentContext context)
116             throws Throwable;
117 
118         protected final String getConnectionDescription() {
119             return connectionDescription;
120         }
121 
122         protected final String getProtocolDescription() {
123             return protocolDescription;
124         }
125 
126         protected final XBridge getBridge(XComponentContext context)
127             throws com.sun.star.uno.Exception
128         {
129             XConnector connector = Connector.create(context);
130             XBridgeFactory factory = UnoRuntime.queryInterface(
131                 XBridgeFactory.class,
132                 context.getServiceManager().createInstanceWithContext(
133                     "com.sun.star.bridge.BridgeFactory", context));
134             System.out.println("Client: Connecting...");
135             XConnection connection = connector.connect(connectionDescription);
136             System.out.println("Client: ...connected...");
137             XBridge bridge = factory.createBridge(
138                 "", protocolDescription, connection, null);
139             System.out.println("Client: ...bridged.");
140             return bridge;
141         }
142 
143         protected final void execute() {
144             int status = CLIENT_FAILED;
145             try {
146                 if (run(Bootstrap.createInitialComponentContext(null))) {
147                     status = CLIENT_DONE;
148                 }
149             } catch (Throwable e) {
150                 e.printStackTrace(System.err);
151             }
152             System.exit(status);
153         }
154     }
155 
156     private static final class Server extends Thread {
157         public Server(XInstanceProvider provider) {
158             super("Server");
159             // assert provider != null;
160             this.provider = provider;
161         }
162 
163         public void run() {
164             try {
165                 XComponentContext context
166                     = Bootstrap.createInitialComponentContext(null);
167                 XAcceptor acceptor = Acceptor.create(context);
168                 XBridgeFactory factory
169                     = UnoRuntime.queryInterface(
170                         XBridgeFactory.class,
171                         context.getServiceManager().createInstanceWithContext(
172                             "com.sun.star.bridge.BridgeFactory", context));
173                 System.out.println("Server: Accepting...");
174                 synchronized (this) {
175                     state = ACCEPTING;
176                     notifyAll();
177                 }
178                 for (;;) {
179                     XConnection connection = acceptor.accept(
180                         connectionDescription);
181                     System.out.println("Server: ...connected...");
182                     XBridge bridge = factory.createBridge(
183                         "", protocolDescription, connection, provider);
184                     System.out.println("Server: ...bridged.");
185                 }
186             } catch (Throwable e) {
187                 e.printStackTrace(System.err);
188             }
189         }
190 
191         public synchronized void waitAccepting() throws InterruptedException {
192             while (state < ACCEPTING) {
193                 wait();
194             }
195         }
196 
197         public synchronized boolean waitDone() throws InterruptedException {
198             while (state <= ACCEPTING) {
199                 wait();
200             }
201             return state == SUCCEEDED;
202         }
203 
204         public synchronized void done(boolean success) {
205             state = success ? SUCCEEDED : FAILED;
206             notifyAll();
207         }
208 
209         private static final int INITIAL = 0;
210         private static final int ACCEPTING = 1;
211         private static final int FAILED = 2;
212         private static final int SUCCEEDED = 3;
213 
214         private final XInstanceProvider provider;
215 
216         private int state = INITIAL;
217     }
218 
219     private static final int TEST_SUCCEEDED = 0;
220     private static final int TEST_FAILED = 1;
221     private static final int TEST_ERROR = 2;
222 
223     private static final int CLIENT_FAILED = 0;
224     private static final int CLIENT_DONE = 123;
225 
226     private static final String connectionDescription
227     = "socket,host=localhost,port=12345";
228     private static final String protocolDescription = "urp";
229 
230     private final Object lock = new Object();
231     private Server server = null;
232 }
233