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