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.AlreadyAcceptingException; 32 import com.sun.star.connection.ConnectionSetupException; 33 import com.sun.star.connection.XAcceptor; 34 import com.sun.star.connection.XConnection; 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.ServerSocket; 41 import java.net.Socket; 42 43 /** 44 * A component that implements the <code>XAcceptor</code> interface. 45 * 46 * <p>The <code>socketAcceptor</code> is a specialized component that uses TCP 47 * sockets for communication. The <code>socketAcceptor</code> is generally used 48 * by the <code>com.sun.star.connection.Acceptor</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 socketAcceptor implements XAcceptor { 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.socketAcceptor"; 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(socketAcceptor.class.getName()) 85 ? FactoryHelper.getServiceFactory(socketAcceptor.class, 86 __serviceName, multiFactory, 87 regKey) 88 : null; 89 } 90 91 /** 92 * Accepts a connection request via the described socket. 93 * 94 * <p>This call blocks until a connection has been established.</p> 95 * 96 * <p>The connection description has the following format: 97 * <code><var>type</var></code><!-- 98 * -->*(<code><var>key</var>=<var>value</var></code>), 99 * where <code><var>type</var></code> should be <code>socket</code> 100 * (ignoring case). Supported keys (ignoring case) currently are 101 * <dl> 102 * <dt><code>host</code> 103 * <dd>The name or address of the accepting interface (defaults to 104 * <code>0</code>, meaning any interface). 105 * <dt><code>port</code> 106 * <dd>The TCP port number to accept on (defaults to <code>6001</code>). 107 * <dt><code>backlog</code> 108 * <dd>The maximum length of the acceptor's queue (defaults to 109 * <code>50</code>). 110 * <dt><code>tcpnodelay</code> 111 * <dd>A flag (<code>0</code>/<code>1</code>) enabling or disabling Nagle's 112 * algorithm on the resulting connection. 113 * </dl></p> 114 * 115 * @param connectionDescription the description of the connection. 116 * @return an <code>XConnection</code> to the client. 117 * 118 * @see com.sun.star.connections.XConnection 119 * @see com.sun.star.connections.XConnector 120 */ 121 public XConnection accept(String connectionDescription) throws 122 AlreadyAcceptingException, ConnectionSetupException, 123 com.sun.star.lang.IllegalArgumentException 124 { 125 ServerSocket serv; 126 synchronized (this) { 127 if (server == null) { 128 ConnectionDescriptor desc 129 = new ConnectionDescriptor(connectionDescription); 130 String host = desc.getHost(); 131 if (host.equals("0")) { 132 host = null; 133 } 134 if (DEBUG) { 135 System.err.println("##### " + getClass().getName() 136 + ".accept: creating ServerSocket " 137 + desc.getPort() + ", " 138 + desc.getBacklog() + ", " + host); 139 } 140 try { 141 server = new ServerSocket(desc.getPort(), desc.getBacklog(), 142 host == null ? null 143 : InetAddress.getByName(host)); 144 } catch (IOException e) { 145 throw new ConnectionSetupException(e.toString()); 146 } 147 acceptingDescription = connectionDescription; 148 tcpNoDelay = desc.getTcpNoDelay(); 149 } else if (!connectionDescription.equals(acceptingDescription)) { 150 throw new AlreadyAcceptingException(acceptingDescription 151 + " vs. " 152 + connectionDescription); 153 } 154 serv = server; 155 } 156 Socket socket; 157 try { 158 socket = serv.accept(); 159 if (DEBUG) { 160 System.err.println("##### " + getClass().getName() 161 + ".accept: accepted " + socket); 162 } 163 if (tcpNoDelay != null) { 164 socket.setTcpNoDelay(tcpNoDelay.booleanValue()); 165 } 166 return new SocketConnection(acceptingDescription, socket); 167 } 168 catch(IOException e) { 169 throw new ConnectionSetupException(e.toString()); 170 } 171 } 172 173 // see com.sun.star.connection.XAcceptor#stopAccepting 174 public void stopAccepting() { 175 ServerSocket serv; 176 synchronized (this) { 177 serv = server; 178 } 179 try { 180 serv.close(); 181 } 182 catch (IOException e) { 183 throw new com.sun.star.uno.RuntimeException(e.toString()); 184 } 185 } 186 187 private static final boolean DEBUG = false; 188 189 private ServerSocket server = null; 190 private String acceptingDescription; 191 private Boolean tcpNoDelay; 192 } 193