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