001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.core.net;
018
019import java.net.Socket;
020import java.net.SocketException;
021
022import org.apache.logging.log4j.core.Core;
023import org.apache.logging.log4j.core.config.plugins.Plugin;
024import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
025import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
026import org.apache.logging.log4j.core.config.plugins.PluginElement;
027import org.apache.logging.log4j.core.util.Builder;
028
029/**
030 * Holds all socket options settable via {@link Socket} methods.
031 */
032@Plugin(name = "SocketOptions", category = Core.CATEGORY_NAME, printObject = true)
033public class SocketOptions implements Builder<SocketOptions>, Cloneable {
034
035    @PluginBuilderFactory
036    public static SocketOptions newBuilder() {
037        return new SocketOptions();
038    }
039
040    @PluginBuilderAttribute
041    private Boolean keepAlive;
042
043    @PluginBuilderAttribute
044    private Boolean oobInline;
045
046    @PluginElement("PerformancePreferences")
047    private SocketPerformancePreferences performancePreferences;
048
049    @PluginBuilderAttribute
050    private Integer receiveBufferSize;
051
052    @PluginBuilderAttribute
053    private Boolean reuseAddress;
054
055    @PluginBuilderAttribute
056    private Rfc1349TrafficClass rfc1349TrafficClass;
057
058    @PluginBuilderAttribute
059    private Integer sendBufferSize;
060
061    @PluginBuilderAttribute
062    private Integer soLinger;
063
064    @PluginBuilderAttribute
065    private Integer soTimeout;
066
067    @PluginBuilderAttribute
068    private Boolean tcpNoDelay;
069
070    @PluginBuilderAttribute
071    private Integer trafficClass;
072
073    public void apply(final Socket socket) throws SocketException {
074        if (keepAlive != null) {
075            socket.setKeepAlive(keepAlive.booleanValue());
076        }
077        if (oobInline != null) {
078            socket.setOOBInline(oobInline.booleanValue());
079        }
080        if (reuseAddress != null) {
081            socket.setReuseAddress(reuseAddress.booleanValue());
082        }
083        if (performancePreferences != null) {
084            performancePreferences.apply(socket);
085        }
086        if (receiveBufferSize != null) {
087            socket.setReceiveBufferSize(receiveBufferSize.intValue());
088        }
089        if (soLinger != null) {
090            socket.setSoLinger(true, soLinger.intValue());
091        }
092        if (soTimeout != null) {
093            socket.setSoTimeout(soTimeout.intValue());
094        }
095        if (tcpNoDelay != null) {
096            socket.setTcpNoDelay(tcpNoDelay.booleanValue());
097        }
098        final Integer actualTrafficClass = getActualTrafficClass();
099        if (actualTrafficClass != null) {
100            socket.setTrafficClass(actualTrafficClass);
101        }
102    }
103
104    @Override
105    public SocketOptions build() {
106        try {
107            return (SocketOptions) clone();
108        } catch (final CloneNotSupportedException e) {
109            throw new IllegalStateException(e);
110        }
111    }
112
113    public Integer getActualTrafficClass() {
114        if (trafficClass != null && rfc1349TrafficClass != null) {
115            throw new IllegalStateException("You MUST not set both customTrafficClass and trafficClass.");
116        }
117        if (trafficClass != null) {
118            return trafficClass;
119        }
120        if (rfc1349TrafficClass != null) {
121            return Integer.valueOf(rfc1349TrafficClass.value());
122        }
123        return null;
124    }
125
126    public SocketPerformancePreferences getPerformancePreferences() {
127        return performancePreferences;
128    }
129
130    public Integer getReceiveBufferSize() {
131        return receiveBufferSize;
132    }
133
134    public Rfc1349TrafficClass getRfc1349TrafficClass() {
135        return rfc1349TrafficClass;
136    }
137
138    public Integer getSendBufferSize() {
139        return sendBufferSize;
140    }
141
142    public Integer getSoLinger() {
143        return soLinger;
144    }
145
146    public Integer getSoTimeout() {
147        return soTimeout;
148    }
149
150    public Integer getTrafficClass() {
151        return trafficClass;
152    }
153
154    public Boolean isKeepAlive() {
155        return keepAlive;
156    }
157
158    public Boolean isOobInline() {
159        return oobInline;
160    }
161
162    public Boolean isReuseAddress() {
163        return reuseAddress;
164    }
165
166    public Boolean isTcpNoDelay() {
167        return tcpNoDelay;
168    }
169
170    public SocketOptions setKeepAlive(final boolean keepAlive) {
171        this.keepAlive = Boolean.valueOf(keepAlive);
172        return this;
173    }
174
175    public SocketOptions setOobInline(final boolean oobInline) {
176        this.oobInline = Boolean.valueOf(oobInline);
177        return this;
178    }
179
180    public SocketOptions setPerformancePreferences(final SocketPerformancePreferences performancePreferences) {
181        this.performancePreferences = performancePreferences;
182        return this;
183    }
184
185    public SocketOptions setReceiveBufferSize(final int receiveBufferSize) {
186        this.receiveBufferSize = receiveBufferSize;
187        return this;
188    }
189
190    public SocketOptions setReuseAddress(final boolean reuseAddress) {
191        this.reuseAddress = Boolean.valueOf(reuseAddress);
192        return this;
193    }
194
195    public SocketOptions setRfc1349TrafficClass(final Rfc1349TrafficClass trafficClass) {
196        this.rfc1349TrafficClass = trafficClass;
197        return this;
198    }
199
200    public SocketOptions setSendBufferSize(final int sendBufferSize) {
201        this.sendBufferSize = sendBufferSize;
202        return this;
203    }
204
205    public SocketOptions setSoLinger(final int soLinger) {
206        this.soLinger = soLinger;
207        return this;
208    }
209
210    public SocketOptions setSoTimeout(final int soTimeout) {
211        this.soTimeout = soTimeout;
212        return this;
213    }
214
215    public SocketOptions setTcpNoDelay(final boolean tcpNoDelay) {
216        this.tcpNoDelay = Boolean.valueOf(tcpNoDelay);
217        return this;
218    }
219
220    public SocketOptions setTrafficClass(final int trafficClass) {
221        this.trafficClass = trafficClass;
222        return this;
223    }
224
225    @Override
226    public String toString() {
227        return "SocketOptions [keepAlive=" + keepAlive + ", oobInline=" + oobInline + ", performancePreferences="
228                + performancePreferences + ", receiveBufferSize=" + receiveBufferSize + ", reuseAddress=" + reuseAddress
229                + ", rfc1349TrafficClass=" + rfc1349TrafficClass + ", sendBufferSize=" + sendBufferSize + ", soLinger="
230                + soLinger + ", soTimeout=" + soTimeout + ", tcpNoDelay=" + tcpNoDelay + ", trafficClass="
231                + trafficClass + "]";
232    }
233}