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 package com.sun.star.lib.connections.socket; 25 26 import com.sun.star.comp.loader.FactoryHelper; 27 import com.sun.star.connection.ConnectionSetupException; 28 import com.sun.star.connection.NoConnectException; 29 import com.sun.star.connection.XConnection; 30 import com.sun.star.connection.XConnector; 31 import com.sun.star.lang.XMultiServiceFactory; 32 import com.sun.star.lang.XSingleServiceFactory; 33 import com.sun.star.registry.XRegistryKey; 34 import java.io.IOException; 35 import java.net.InetAddress; 36 import java.net.Socket; 37 import java.net.UnknownHostException; 38 39 /** 40 * A component that implements the <code>XConnector</code> interface. 41 * 42 * <p>The <code>socketConnector</code> is a specialized component that uses TCP 43 * sockets for communication. The <code>socketConnector</code> is generally 44 * used by the <code>com.sun.star.connection.Connector</code> service.</p> 45 * 46 * @see com.sun.star.connections.XAcceptor 47 * @see com.sun.star.connections.XConnection 48 * @see com.sun.star.connections.XConnector 49 * @see com.sun.star.loader.JavaLoader 50 * 51 * @since UDK 1.0 52 */ 53 public final class socketConnector implements XConnector { 54 /** 55 * The name of the service. 56 * 57 * <p>The <code>JavaLoader</code> acceses this through reflection.</p> 58 * 59 * @see com.sun.star.comp.loader.JavaLoader 60 */ 61 public static final String __serviceName 62 = "com.sun.star.connection.socketConnector"; 63 64 /** 65 * Returns a factory for creating the service. 66 * 67 * <p>This method is called by the <code>JavaLoader</code>.</p> 68 * 69 * @param implName the name of the implementation for which a service is 70 * requested. 71 * @param multiFactory the service manager to be used (if needed). 72 * @param regKey the registry key. 73 * @return an <code>XSingleServiceFactory</code> for creating the component. 74 * 75 * @see com.sun.star.comp.loader.JavaLoader 76 */ __getServiceFactory( String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey)77 public static XSingleServiceFactory __getServiceFactory( 78 String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) 79 { 80 return implName.equals(socketConnector.class.getName()) 81 ? FactoryHelper.getServiceFactory(socketConnector.class, 82 __serviceName, multiFactory, 83 regKey) 84 : null; 85 } 86 87 /** 88 * Connects via the described socket to a waiting server. 89 * 90 * <p>The connection description has the following format: 91 * <code><var>type</var></code><!-- 92 * -->*(<code><var>key</var>=<var>value</var></code>), 93 * where <code><var>type</var></code> should be <code>socket</code> 94 * (ignoring case). Supported keys (ignoring case) currently are 95 * <dl> 96 * <dt><code>host</code> 97 * <dd>The name or address of the server. Must be present. 98 * <dt><code>port</code> 99 * <dd>The TCP port number of the server (defaults to <code>6001</code>). 100 * <dt><code>tcpnodelay</code> 101 * <dd>A flag (<code>0</code>/<code>1</code>) enabling or disabling Nagle's 102 * algorithm on the resulting connection. 103 * </dl></p> 104 * 105 * @param connectionDescription the description of the connection. 106 * @return an <code>XConnection</code> to the server. 107 * 108 * @see com.sun.star.connections.XAcceptor 109 * @see com.sun.star.connections.XConnection 110 */ connect(String connectionDescription)111 public synchronized XConnection connect(String connectionDescription) 112 throws NoConnectException, ConnectionSetupException 113 { 114 if (connected) { 115 throw new ConnectionSetupException("alread connected"); 116 } 117 ConnectionDescriptor desc; 118 try { 119 desc = new ConnectionDescriptor(connectionDescription); 120 } catch (com.sun.star.lang.IllegalArgumentException e) { 121 throw new ConnectionSetupException(e.toString()); 122 } 123 if (desc.getHost() == null) { 124 throw new ConnectionSetupException("host parameter missing"); 125 } 126 // Try all (IPv4 and IPv6) addresses, in case this client is on a 127 // dual-stack host and the server process is an IPv4-only process, also 128 // on a dual-stack host (see Stevens, Fenner, Rudoff: "Unix Network 129 // Programming, Volume 1: The Sockets Networking API, 3rd Edition", 130 // p. 359): 131 InetAddress[] adr; 132 try { 133 adr = InetAddress.getAllByName(desc.getHost()); 134 } catch (UnknownHostException e) { 135 throw new ConnectionSetupException(e.toString()); 136 } 137 Socket socket = null; 138 for (int i = 0; i < adr.length; ++i) { 139 try { 140 socket = new Socket(adr[i], desc.getPort()); 141 break; 142 } catch (IOException e) { 143 if (i == adr.length - 1) { 144 throw new NoConnectException(e.toString()); 145 } 146 } 147 } 148 XConnection con; 149 try { 150 if (desc.getTcpNoDelay() != null) { 151 socket.setTcpNoDelay(desc.getTcpNoDelay().booleanValue()); 152 } 153 con = new SocketConnection(connectionDescription, socket); 154 } catch (IOException e) { 155 throw new NoConnectException(e.toString()); 156 } 157 connected = true; 158 return con; 159 } 160 161 private boolean connected = false; 162 } 163