001/* 002 * Copyright 2012-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2012-2024 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2012-2024 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.util; 037 038 039 040import java.io.IOException; 041import java.net.InetAddress; 042import java.net.Socket; 043import javax.net.SocketFactory; 044 045 046 047/** 048 * This class provides an implementation of a Java socket factory that will 049 * wrap a provided socket factory but will synchronize on each use of that 050 * factory to ensure that only a single thread may use that factory to create 051 * a socket at any given time. 052 */ 053@NotMutable() 054@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 055public final class SynchronizedSocketFactory 056 extends SocketFactory 057{ 058 // The wrapped socket factory. 059 @NotNull private final SocketFactory factory; 060 061 062 063 /** 064 * Creates a new synchronous socket factory instance that will wrap the 065 * provided socket factory. 066 * 067 * @param factory The socket factory to be wrapped. 068 */ 069 public SynchronizedSocketFactory(@NotNull final SocketFactory factory) 070 { 071 this.factory = factory; 072 } 073 074 075 076 /** 077 * Retrieves the {@code SocketFactory} instance wrapped by this synchronized 078 * socket factory. 079 * 080 * @return The {@code SocketFactory} instance wrapped by this synchronized 081 * socket factory. 082 */ 083 @NotNull() 084 public SocketFactory getWrappedSocketFactory() 085 { 086 return factory; 087 } 088 089 090 091 /** 092 * Creates a new socket to the specified server. 093 * 094 * @param host The host to which the connection should be established. 095 * @param port The port to which the connection should be established. 096 * 097 * @return The socket that was created. 098 * 099 * @throws IOException If a problem occurs while creating the socket. 100 */ 101 @Override() 102 @NotNull() 103 public Socket createSocket(@NotNull final String host, final int port) 104 throws IOException 105 { 106 synchronized (factory) 107 { 108 return factory.createSocket(host, port); 109 } 110 } 111 112 113 114 /** 115 * Creates a new socket to the specified server. 116 * 117 * @param host The host to which the connection should be 118 * established. 119 * @param port The port to which the connection should be 120 * established. 121 * @param localAddress The local address to use for the connection. 122 * @param localPort The local port to use for the connection. 123 * 124 * @return The socket that was created. 125 * 126 * @throws IOException If a problem occurs while creating the socket. 127 */ 128 @Override() 129 @NotNull() 130 public Socket createSocket(@NotNull final String host, final int port, 131 @NotNull final InetAddress localAddress, 132 final int localPort) 133 throws IOException 134 { 135 synchronized (factory) 136 { 137 return factory.createSocket(host, port, localAddress, localPort); 138 } 139 } 140 141 142 143 /** 144 * Creates a new socket to the specified server. 145 * 146 * @param address The address to which the connection should be established. 147 * @param port The port to which the connection should be established. 148 * 149 * @return The socket that was created. 150 * 151 * @throws IOException If a problem occurs while creating the socket. 152 */ 153 @Override() 154 @NotNull() 155 public Socket createSocket(@NotNull final InetAddress address, final int port) 156 throws IOException 157 { 158 synchronized (factory) 159 { 160 return factory.createSocket(address, port); 161 } 162 } 163 164 165 166 /** 167 * Creates a new socket to the specified server. 168 * 169 * @param address The address to which the connection should be 170 * established. 171 * @param port The port to which the connection should be 172 * established. 173 * @param localAddress The local address to use for the connection. 174 * @param localPort The local port to use for the connection. 175 * 176 * @return The socket that was created. 177 * 178 * @throws IOException If a problem occurs while creating the socket. 179 */ 180 @Override() 181 @NotNull() 182 public Socket createSocket(@NotNull final InetAddress address, final int port, 183 @NotNull final InetAddress localAddress, 184 final int localPort) 185 throws IOException 186 { 187 synchronized (factory) 188 { 189 return factory.createSocket(address, port, localAddress, localPort); 190 } 191 } 192}