1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.spdy.api;
20
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25
26 public class Settings implements Iterable<Settings.Setting>
27 {
28 private Map<ID, Settings.Setting> settings = new HashMap<>();
29
30 public Settings()
31 {
32 }
33
34 public Settings(Settings original, boolean immutable)
35 {
36 Map<ID, Settings.Setting> copy = new HashMap<>(original.size());
37 copy.putAll(original.settings);
38 settings = immutable ? Collections.unmodifiableMap(copy) : copy;
39 }
40
41 public Setting get(ID id)
42 {
43 return settings.get(id);
44 }
45
46 public void put(Setting setting)
47 {
48 settings.put(setting.id(), setting);
49 }
50
51 public Setting remove(ID id)
52 {
53 return settings.remove(id);
54 }
55
56 public int size()
57 {
58 return settings.size();
59 }
60
61 public void clear()
62 {
63 settings.clear();
64 }
65
66 @Override
67 public boolean equals(Object obj)
68 {
69 if (this == obj)
70 return true;
71 if (obj == null || getClass() != obj.getClass())
72 return false;
73 Settings that = (Settings)obj;
74 return settings.equals(that.settings);
75 }
76
77 @Override
78 public int hashCode()
79 {
80 return settings.hashCode();
81 }
82
83 @Override
84 public Iterator<Setting> iterator()
85 {
86 return settings.values().iterator();
87 }
88
89 @Override
90 public String toString()
91 {
92 return settings.toString();
93 }
94
95 public static final class ID
96 {
97 public static ID UPLOAD_BANDWIDTH = new ID(1);
98 public static ID DOWNLOAD_BANDWIDTH = new ID(2);
99 public static ID ROUND_TRIP_TIME = new ID(3);
100 public static ID MAX_CONCURRENT_STREAMS = new ID(4);
101 public static ID CURRENT_CONGESTION_WINDOW = new ID(5);
102 public static ID DOWNLOAD_RETRANSMISSION_RATE = new ID(6);
103 public static ID INITIAL_WINDOW_SIZE = new ID(7);
104
105 public synchronized static ID from(int code)
106 {
107 ID id = Codes.codes.get(code);
108 if (id == null)
109 id = new ID(code);
110 return id;
111 }
112
113 private final int code;
114
115 private ID(int code)
116 {
117 this.code = code;
118 Codes.codes.put(code, this);
119 }
120
121 public int code()
122 {
123 return code;
124 }
125
126 @Override
127 public String toString()
128 {
129 return String.valueOf(code);
130 }
131
132 private static class Codes
133 {
134 private static final Map<Integer, ID> codes = new HashMap<>();
135 }
136 }
137
138 public static enum Flag
139 {
140 NONE((byte)0),
141 PERSIST((byte)1),
142 PERSISTED((byte)2);
143
144 public static Flag from(byte code)
145 {
146 return Codes.codes.get(code);
147 }
148
149 private final byte code;
150
151 private Flag(byte code)
152 {
153 this.code = code;
154 Codes.codes.put(code, this);
155 }
156
157 public byte code()
158 {
159 return code;
160 }
161
162 private static class Codes
163 {
164 private static final Map<Byte, Flag> codes = new HashMap<>();
165 }
166 }
167
168 public static class Setting
169 {
170 private final ID id;
171 private final Flag flag;
172 private final int value;
173
174 public Setting(ID id, int value)
175 {
176 this(id, Flag.NONE, value);
177 }
178
179 public Setting(ID id, Flag flag, int value)
180 {
181 this.id = id;
182 this.flag = flag;
183 this.value = value;
184 }
185
186 public ID id()
187 {
188 return id;
189 }
190
191 public Flag flag()
192 {
193 return flag;
194 }
195
196 public int value()
197 {
198 return value;
199 }
200
201 @Override
202 public boolean equals(Object obj)
203 {
204 if (this == obj)
205 return true;
206 if (obj == null || getClass() != obj.getClass())
207 return false;
208 Setting that = (Setting)obj;
209 return value == that.value && flag == that.flag && id == that.id;
210 }
211
212 @Override
213 public int hashCode()
214 {
215 int result = id.hashCode();
216 result = 31 * result + flag.hashCode();
217 result = 31 * result + value;
218 return result;
219 }
220
221 @Override
222 public String toString()
223 {
224 return String.format("[id=%s,flags=%s:value=%d]", id(), flag(), value());
225 }
226 }
227 }