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 package basicrunner.basichelper;
24 
25 import com.sun.star.lang.XInitialization;
26 import com.sun.star.lang.XServiceInfo;
27 import com.sun.star.lang.XTypeProvider;
28 import com.sun.star.uno.Type;
29 import com.sun.star.connection.XConnector;
30 import com.sun.star.connection.XConnection;
31 import com.sun.star.connection.ConnectionSetupException;
32 import com.sun.star.connection.NoConnectException;
33 import com.sun.star.container.XNameAccess;
34 import com.sun.star.container.NoSuchElementException;
35 import com.sun.star.uno.UnoRuntime;
36 import com.sun.star.lang.XSingleServiceFactory;
37 
38 /**
39  * This is a special service that is used in testing Acceptor
40  * component in BASIC. This componennt creates a separate thread
41  * that tries to connect to BASIC's acceptor. After successfull
42  * connection it writes a connectionString to XConnection.
43  */
44  public class Connector implements XServiceInfo, XSingleServiceFactory {
45     /** The service name of this class **/
46     static final String __serviceName = "basichelper.Connector";
47     /** The Connector implementation **/
48     static ConnectorImpl oConnector = null;
49 
50    /** Create a connector.
51     */
52    public Connector() {
53         oConnector = new ConnectorImpl();
54     }
55 
56     /**
57      * Returns an instance of the connector.
58      * Arguments are not supported here and will be ignored.
59      * @param args The arguments.
60      * @return The connector.
61      */
62     public Object createInstanceWithArguments(Object[] args) {
63         return oConnector;
64     }
65 
66     /**
67      * Returns an instance of the connector.
68      * @return The connector.
69      */
70     public Object createInstance() {
71         return createInstanceWithArguments(null);
72     }
73 
74     /**
75      * Get a unique id for this implementation.
76      * @return The id.
77      */
78     public byte[] getImplementationId() {
79         return toString().getBytes();
80     }
81 
82     /**
83      * Return all implemented types of this class.
84      * @return The implemented UNO types.
85      */
86     public Type[] getTypes() {
87         Class interfaces[] = getClass().getInterfaces();
88 
89         Type types[] = new Type[interfaces.length];
90         for(int i = 0; i < interfaces.length; ++ i)
91             types[i] = new Type(interfaces[i]);
92 
93         return types;
94     }
95 
96     /** Is this servioce supported?
97      * @param name The service name.
98      * @return True, if the service is supported.
99      */
100     public boolean supportsService(String name) {
101         return __serviceName.equals(name);
102     }
103 
104     /**
105      * Get all supported service names.
106      * @return All supported servcices.
107      */
108     public String[] getSupportedServiceNames() {
109         return new String[] {__serviceName};
110     }
111 
112     /**
113      * Get the implementation name of this class.
114      * @return The implementation name.
115      */
116     public String getImplementationName() {
117         return getClass().getName();
118     }
119 }
120 
121 /**
122  * The actual implementation of the connector
123  * @see com.sun.star.lang.XInitialization
124  * @see com.sun.star.lang.XTypeProvider
125  * @see com.sun.star.container.XNameAccess
126  */
127 class ConnectorImpl implements XInitialization, XTypeProvider, XNameAccess {
128     static String aState;
129     static Integer iTimeout;
130 
131     /**
132      * Construct a new connector.
133      */
134     public ConnectorImpl() {
135         aState = "just created";
136         iTimeout = new Integer(3000);
137     }
138 
139     /**
140      * Method initialize() creates a new thread that will try to connect to
141      * Acceptor for a few seconds. One should pass as parameters an array,
142      * where element 0 is an instance of Connector and element 1 is a
143      * connection string (the same as in Acceptor)
144      * @param parm1 An instance of XConnector.
145      * @see com.sun.star.connection.XConnector
146      * @throws Exception Is thrown, when initialize fails.
147      */
148     public void initialize(Object[] parm1) throws com.sun.star.uno.Exception {
149         aState = "just initialized";
150         XConnector cntr = (XConnector)UnoRuntime.queryInterface(
151                                                 XConnector.class, parm1[0]);
152         ConnThread aThread = new ConnThread(cntr, (String)parm1[1]);
153         aThread.start();
154     }
155 
156     /**
157      * Get the element names
158      * @return All element names.
159      */
160     public String[] getElementNames() {
161         return new String[]{"State", "Timeout"};
162     }
163 
164     /**
165      * Does this element exist?
166      * @param name The element name.
167      * @return True, if the name exists.
168      */
169     public boolean hasByName(String name) {
170         return (name.equals("State") || name.equals("Timeout"));
171     }
172 
173     /**
174      * Get an element by its name.
175      * @param name The name of the element.
176      * @return The value of the element.
177      * @throws NoSuchElementException The element does not exist.
178      */
179     public Object getByName(String name) throws NoSuchElementException{
180         if (name.equals("State"))
181             return aState;
182         else if (name.equals("Timeout"))
183             return iTimeout;
184         else
185             throw new NoSuchElementException();
186     }
187 
188     /**
189      * Are there elements
190      * @return Always true.
191      */
192     public boolean hasElements() {
193         return true;
194     }
195 
196     /**
197      * Get element type.
198      * @return null.
199      */
200     public Type getElementType() {
201         return null;
202     }
203 
204     /**
205      * Get a unique id for this implementation.
206      * @return The id.
207      */
208     public byte[] getImplementationId() {
209         return toString().getBytes();
210     }
211 
212     /**
213      * Return all implemented types of this class.
214      * @return The implemented UNO types.
215      */
216     public Type[] getTypes() {
217         Class interfaces[] = getClass().getInterfaces();
218 
219         Type types[] = new Type[interfaces.length];
220         for(int i = 0; i < interfaces.length; ++ i)
221             types[i] = new Type(interfaces[i]);
222 
223         return types;
224     }
225 }
226 
227 /**
228  * A connector thread
229  */
230 class ConnThread extends Thread {
231     String connStr;
232     XConnector oConnector;
233 
234     /**Construct the thread.
235      * @param oCntr A connector.
236      * @param cStr The conection string.
237      */
238     public ConnThread(XConnector oCntr, String cStr){
239         connStr = cStr;
240         oConnector = oCntr;
241     }
242 
243     /**
244      * Run the thread.
245      */
246     public void run(){
247         try {
248             Thread.sleep(ConnectorImpl.iTimeout.intValue());
249             ConnectorImpl.aState = "before connection";
250             XConnection oConnection = oConnector.connect(connStr);
251             if (oConnection != null) {
252                 ConnectorImpl.aState = "connected";
253                 oConnection.write(connStr.getBytes());
254                 oConnection.write(new byte[]{0});
255             } else
256                 ConnectorImpl.aState = "XConnection is null";
257         } catch (ConnectionSetupException e) {
258             ConnectorImpl.aState = "ConnectionSetupException";
259             throw new RuntimeException(e.toString());
260         } catch (NoConnectException e) {
261             ConnectorImpl.aState = "NoConnectException";
262             throw new RuntimeException(e.toString());
263         } catch (Exception e) {
264             ConnectorImpl.aState = "error";
265             throw new RuntimeException("Can't sleep exception");
266         }
267     }
268 }
269