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  * This software consists of voluntary contributions made by many
22  * individuals on behalf of the Apache Software Foundation.  For more
23  * information on the Apache Software Foundation, please see
24  * <http://www.apache.org/>.
25  *
26  */

27
28 package org.apache.http.config;
29
30 import java.nio.charset.Charset;
31 import java.nio.charset.CodingErrorAction;
32
33 import org.apache.http.Consts;
34 import org.apache.http.annotation.ThreadingBehavior;
35 import org.apache.http.annotation.Contract;
36 import org.apache.http.util.Args;
37
38 /**
39  * HTTP connection configuration.
40  *
41  * @since 4.3
42  */

43 @Contract(threading = ThreadingBehavior.IMMUTABLE)
44 public class ConnectionConfig implements Cloneable {
45
46     public static final ConnectionConfig DEFAULT = new Builder().build();
47
48     private final int bufferSize;
49     private final int fragmentSizeHint;
50     private final Charset charset;
51     private final CodingErrorAction malformedInputAction;
52     private final CodingErrorAction unmappableInputAction;
53     private final MessageConstraints messageConstraints;
54
55     ConnectionConfig(
56             final int bufferSize,
57             final int fragmentSizeHint,
58             final Charset charset,
59             final CodingErrorAction malformedInputAction,
60             final CodingErrorAction unmappableInputAction,
61             final MessageConstraints messageConstraints) {
62         super();
63         this.bufferSize = bufferSize;
64         this.fragmentSizeHint = fragmentSizeHint;
65         this.charset = charset;
66         this.malformedInputAction = malformedInputAction;
67         this.unmappableInputAction = unmappableInputAction;
68         this.messageConstraints = messageConstraints;
69     }
70
71     public int getBufferSize() {
72         return bufferSize;
73     }
74
75     public int getFragmentSizeHint() {
76         return fragmentSizeHint;
77     }
78
79     public Charset getCharset() {
80         return charset;
81     }
82
83     public CodingErrorAction getMalformedInputAction() {
84         return malformedInputAction;
85     }
86
87     public CodingErrorAction getUnmappableInputAction() {
88         return unmappableInputAction;
89     }
90
91     public MessageConstraints getMessageConstraints() {
92         return messageConstraints;
93     }
94
95     @Override
96     protected ConnectionConfig clone() throws CloneNotSupportedException {
97         return (ConnectionConfig) super.clone();
98     }
99
100     @Override
101     public String toString() {
102         final StringBuilder builder = new StringBuilder();
103         builder.append("[bufferSize=").append(this.bufferSize)
104                 .append(", fragmentSizeHint=").append(this.fragmentSizeHint)
105                 .append(", charset=").append(this.charset)
106                 .append(", malformedInputAction=").append(this.malformedInputAction)
107                 .append(", unmappableInputAction=").append(this.unmappableInputAction)
108                 .append(", messageConstraints=").append(this.messageConstraints)
109                 .append("]");
110         return builder.toString();
111     }
112
113     public static ConnectionConfig.Builder custom() {
114         return new Builder();
115     }
116
117     public static ConnectionConfig.Builder copy(final ConnectionConfig config) {
118         Args.notNull(config, "Connection config");
119         return new Builder()
120             .setBufferSize(config.getBufferSize())
121             .setCharset(config.getCharset())
122             .setFragmentSizeHint(config.getFragmentSizeHint())
123             .setMalformedInputAction(config.getMalformedInputAction())
124             .setUnmappableInputAction(config.getUnmappableInputAction())
125             .setMessageConstraints(config.getMessageConstraints());
126     }
127
128     public static class Builder {
129
130         private int bufferSize;
131         private int fragmentSizeHint;
132         private Charset charset;
133         private CodingErrorAction malformedInputAction;
134         private CodingErrorAction unmappableInputAction;
135         private MessageConstraints messageConstraints;
136
137         Builder() {
138             this.fragmentSizeHint = -1;
139         }
140
141         public Builder setBufferSize(final int bufferSize) {
142             this.bufferSize = bufferSize;
143             return this;
144         }
145
146         public Builder setFragmentSizeHint(final int fragmentSizeHint) {
147             this.fragmentSizeHint = fragmentSizeHint;
148             return this;
149         }
150
151         public Builder setCharset(final Charset charset) {
152             this.charset = charset;
153             return this;
154         }
155
156         public Builder setMalformedInputAction(final CodingErrorAction malformedInputAction) {
157             this.malformedInputAction = malformedInputAction;
158             if (malformedInputAction != null && this.charset == null) {
159                 this.charset = Consts.ASCII;
160             }
161             return this;
162         }
163
164         public Builder setUnmappableInputAction(final CodingErrorAction unmappableInputAction) {
165             this.unmappableInputAction = unmappableInputAction;
166             if (unmappableInputAction != null && this.charset == null) {
167                 this.charset = Consts.ASCII;
168             }
169             return this;
170         }
171
172         public Builder setMessageConstraints(final MessageConstraints messageConstraints) {
173             this.messageConstraints = messageConstraints;
174             return this;
175         }
176
177         public ConnectionConfig build() {
178             Charset cs = charset;
179             if (cs == null && (malformedInputAction != null || unmappableInputAction != null)) {
180                 cs = Consts.ASCII;
181             }
182             final int bufSize = this.bufferSize > 0 ? this.bufferSize : 8 * 1024;
183             final int fragmentHintSize  = this.fragmentSizeHint >= 0 ? this.fragmentSizeHint : bufSize;
184             return new ConnectionConfig(
185                     bufSize,
186                     fragmentHintSize,
187                     cs,
188                     malformedInputAction,
189                     unmappableInputAction,
190                     messageConstraints);
191         }
192
193     }
194
195 }
196