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