1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.bootstrap;
17
18 import org.jboss.netty.channel.Channel;
19 import org.jboss.netty.channel.ChannelFactory;
20 import org.jboss.netty.channel.ChannelHandler;
21 import org.jboss.netty.channel.ChannelPipeline;
22 import org.jboss.netty.channel.ChannelPipelineFactory;
23 import org.jboss.netty.util.ExternalResourceReleasable;
24
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.LinkedHashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.TreeMap;
32
33 import static org.jboss.netty.channel.Channels.*;
34
35
36
37
38
39
40
41
42
43
44
45 public class Bootstrap implements ExternalResourceReleasable {
46
47 private volatile ChannelFactory factory;
48 private volatile ChannelPipeline pipeline = pipeline();
49 private volatile ChannelPipelineFactory pipelineFactory = pipelineFactory(pipeline);
50 private volatile Map<String, Object> options = new HashMap<String, Object>();
51
52
53
54
55
56
57 protected Bootstrap() {
58 }
59
60
61
62
63 protected Bootstrap(ChannelFactory channelFactory) {
64 setFactory(channelFactory);
65 }
66
67
68
69
70
71
72
73
74
75
76 public ChannelFactory getFactory() {
77 ChannelFactory factory = this.factory;
78 if (factory == null) {
79 throw new IllegalStateException(
80 "factory is not set yet.");
81 }
82 return factory;
83 }
84
85
86
87
88
89
90
91
92
93 public void setFactory(ChannelFactory factory) {
94 if (factory == null) {
95 throw new NullPointerException("factory");
96 }
97 if (this.factory != null) {
98 throw new IllegalStateException(
99 "factory can't change once set.");
100 }
101 this.factory = factory;
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public ChannelPipeline getPipeline() {
126 ChannelPipeline pipeline = this.pipeline;
127 if (pipeline == null) {
128 throw new IllegalStateException(
129 "getPipeline() cannot be called " +
130 "if setPipelineFactory() was called.");
131 }
132 return pipeline;
133 }
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public void setPipeline(ChannelPipeline pipeline) {
154 if (pipeline == null) {
155 throw new NullPointerException("pipeline");
156 }
157 this.pipeline = pipeline;
158 pipelineFactory = pipelineFactory(pipeline);
159 }
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179 public Map<String, ChannelHandler> getPipelineAsMap() {
180 ChannelPipeline pipeline = this.pipeline;
181 if (pipeline == null) {
182 throw new IllegalStateException("pipelineFactory in use");
183 }
184 return pipeline.toMap();
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 public void setPipelineAsMap(Map<String, ChannelHandler> pipelineMap) {
205 if (pipelineMap == null) {
206 throw new NullPointerException("pipelineMap");
207 }
208
209 if (!isOrderedMap(pipelineMap)) {
210 throw new IllegalArgumentException(
211 "pipelineMap is not an ordered map. " +
212 "Please use " +
213 LinkedHashMap.class.getName() + '.');
214 }
215
216 ChannelPipeline pipeline = pipeline();
217 for (Map.Entry<String, ChannelHandler> e: pipelineMap.entrySet()) {
218 pipeline.addLast(e.getKey(), e.getValue());
219 }
220
221 setPipeline(pipeline);
222 }
223
224
225
226
227
228
229
230 public ChannelPipelineFactory getPipelineFactory() {
231 return pipelineFactory;
232 }
233
234
235
236
237
238
239
240
241
242
243
244 public void setPipelineFactory(ChannelPipelineFactory pipelineFactory) {
245 if (pipelineFactory == null) {
246 throw new NullPointerException("pipelineFactory");
247 }
248 pipeline = null;
249 this.pipelineFactory = pipelineFactory;
250 }
251
252
253
254
255
256
257 public Map<String, Object> getOptions() {
258 return new TreeMap<String, Object>(options);
259 }
260
261
262
263
264
265
266 public void setOptions(Map<String, Object> options) {
267 if (options == null) {
268 throw new NullPointerException("options");
269 }
270 this.options = new HashMap<String, Object>(options);
271 }
272
273
274
275
276
277
278
279
280
281
282
283 public Object getOption(String key) {
284 if (key == null) {
285 throw new NullPointerException("key");
286 }
287 return options.get(key);
288 }
289
290
291
292
293
294
295
296
297
298
299
300 public void setOption(String key, Object value) {
301 if (key == null) {
302 throw new NullPointerException("key");
303 }
304 if (value == null) {
305 options.remove(key);
306 } else {
307 options.put(key, value);
308 }
309 }
310
311
312
313
314
315 public void releaseExternalResources() {
316 ChannelFactory factory = this.factory;
317 if (factory != null) {
318 factory.releaseExternalResources();
319 }
320 }
321
322
323
324
325
326 @SuppressWarnings({ "unchecked", "rawtypes" })
327 static boolean isOrderedMap(Map<?, ?> map) {
328 Class<?> mapType = map.getClass();
329 if (LinkedHashMap.class.isAssignableFrom(mapType)) {
330
331 return true;
332 }
333
334
335
336
337 Class<?> type = mapType;
338 while (type != null) {
339 for (Class<?> i: type.getInterfaces()) {
340 if (i.getName().endsWith("OrderedMap")) {
341
342
343 return true;
344 }
345 }
346 type = type.getSuperclass();
347 }
348
349
350
351 Map newMap;
352 try {
353 newMap = (Map) mapType.newInstance();
354 } catch (Exception e) {
355
356 return false;
357 }
358
359
360 List<String> expectedKeys = new ArrayList<String>();
361 String dummyValue = "dummyValue";
362 for (short element: ORDER_TEST_SAMPLES) {
363 String key = String.valueOf(element);
364 newMap.put(key, dummyValue);
365 expectedKeys.add(key);
366
367 Iterator<String> it = expectedKeys.iterator();
368 for (Object actualKey: newMap.keySet()) {
369 if (!it.next().equals(actualKey)) {
370
371 return false;
372 }
373 }
374 }
375
376
377 return true;
378 }
379
380 private static final short[] ORDER_TEST_SAMPLES = {
381 682, 807, 637, 358, 570, 828, 407, 319,
382 105, 41, 563, 544, 518, 298, 418, 50,
383 156, 769, 984, 503, 191, 578, 309, 710,
384 327, 720, 591, 939, 374, 707, 43, 463,
385 227, 174, 30, 531, 135, 930, 190, 823,
386 925, 835, 328, 239, 415, 500, 144, 460,
387 83, 774, 921, 4, 95, 468, 687, 493,
388 991, 436, 245, 742, 149, 821, 142, 782,
389 297, 918, 917, 424, 978, 992, 79, 906,
390 535, 515, 850, 80, 125, 378, 307, 883,
391 836, 160, 27, 630, 668, 226, 560, 698,
392 467, 829, 476, 163, 977, 367, 325, 184,
393 204, 312, 486, 53, 179, 592, 252, 750,
394 893, 517, 937, 124, 148, 719, 973, 566,
395 405, 449, 452, 777, 349, 761, 167, 783,
396 220, 802, 117, 604, 216, 363, 120, 621,
397 219, 182, 817, 244, 438, 465, 934, 888,
398 628, 209, 631, 17, 870, 679, 826, 945,
399 680, 848, 974, 573, 626, 865, 109, 317,
400 91, 494, 965, 473, 725, 388, 302, 936,
401 660, 150, 122, 949, 295, 392, 63, 634,
402 772, 143, 990, 895, 538, 59, 541, 32,
403 669, 321, 811, 756, 82, 955, 953, 636,
404 390, 162, 688, 444, 70, 590, 183, 745,
405 543, 666, 951, 642, 747, 765, 98, 469,
406 884, 929, 178, 721, 994, 840, 353, 726,
407 940, 759, 624, 919, 667, 629, 272, 979,
408 326, 608, 453, 11, 322, 347, 647, 354,
409 381, 746, 472, 890, 249, 536, 733, 404,
410 170, 959, 34, 899, 195, 651, 140, 856,
411 201, 237, 51, 933, 268, 849, 294, 115,
412 157, 14, 854, 373, 186, 872, 71, 523,
413 931, 952, 655, 561, 607, 862, 554, 661,
414 313, 909, 511, 752, 986, 311, 287, 775,
415 505, 878, 422, 103, 299, 119, 107, 344,
416 487, 776, 445, 218, 549, 697, 454, 6,
417 462, 455, 52, 481, 594, 126, 112, 66,
418 877, 172, 153, 912, 834, 741, 610, 915,
419 964, 831, 575, 714, 250, 461, 814, 913,
420 369, 542, 882, 851, 427, 838, 867, 507,
421 434, 569, 20, 950, 792, 605, 798, 962,
422 923, 258, 972, 762, 809, 843, 674, 448,
423 280, 495, 285, 822, 283, 147, 451, 993,
424 794, 982, 748, 189, 274, 96, 73, 810,
425 401, 261, 277, 346, 527, 645, 601, 868,
426 248, 879, 371, 428, 559, 278, 265, 62,
427 225, 853, 483, 771, 9, 8, 339, 653,
428 263, 28, 477, 995, 208, 880, 292, 480,
429 516, 457, 286, 897, 21, 852, 971, 658,
430 623, 528, 316, 471, 860, 306, 638, 711,
431 875, 671, 108, 158, 646, 24, 257, 724,
432 193, 341, 902, 599, 565, 334, 506, 684,
433 960, 780, 429, 801, 910, 308, 383, 901,
434 489, 81, 512, 164, 755, 514, 723, 141,
435 296, 958, 686, 15, 799, 579, 598, 558,
436 414, 64, 420, 730, 256, 131, 45, 129,
437 259, 338, 999, 175, 740, 790, 324, 985,
438 896, 482, 841, 606, 377, 111, 372, 699,
439 988, 233, 243, 203, 781, 969, 903, 662,
440 632, 301, 44, 981, 36, 412, 946, 816,
441 284, 447, 214, 672, 758, 954, 804, 2,
442 928, 886, 421, 596, 574, 16, 892, 68,
443 546, 522, 490, 873, 656, 696, 864, 130,
444 40, 393, 926, 394, 932, 876, 664, 293,
445 154, 916, 55, 196, 842, 498, 177, 948,
446 540, 127, 271, 113, 844, 576, 132, 943,
447 12, 123, 291, 31, 212, 529, 547, 171,
448 582, 609, 793, 830, 221, 440, 568, 118,
449 406, 194, 827, 360, 622, 389, 800, 571,
450 213, 262, 403, 408, 881, 289, 635, 967,
451 432, 376, 649, 832, 857, 717, 145, 510,
452 159, 980, 683, 580, 484, 379, 246, 88,
453 567, 320, 643, 7, 924, 397, 10, 787,
454 845, 779, 670, 716, 19, 600, 382, 0,
455 210, 665, 228, 97, 266, 90, 304, 456,
456 180, 152, 425, 310, 768, 223, 702, 997,
457 577, 663, 290, 537, 416, 426, 914, 691,
458 23, 281, 497, 508, 48, 681, 581, 728,
459 99, 795, 530, 871, 957, 889, 206, 813,
460 839, 709, 805, 253, 151, 613, 65, 654,
461 93, 639, 784, 891, 352, 67, 430, 754,
462 76, 187, 443, 676, 362, 961, 874, 330,
463 331, 384, 85, 217, 855, 818, 738, 361,
464 314, 3, 615, 520, 355, 920, 689, 22,
465 188, 49, 904, 935, 136, 475, 693, 749,
466 519, 812, 100, 207, 963, 364, 464, 572,
467 731, 230, 833, 385, 499, 545, 273, 232,
468 398, 478, 975, 564, 399, 504, 35, 562,
469 938, 211, 26, 337, 54, 614, 586, 433,
470 450, 763, 238, 305, 941, 370, 885, 837,
471 234, 110, 137, 395, 368, 695, 342, 907,
472 396, 474, 176, 737, 796, 446, 37, 894,
473 727, 648, 431, 1, 366, 525, 553, 704,
474 329, 627, 479, 33, 492, 260, 241, 86,
475 185, 491, 966, 247, 13, 587, 602, 409,
476 335, 650, 235, 611, 470, 442, 597, 254,
477 343, 539, 146, 585, 593, 641, 770, 94,
478 976, 705, 181, 255, 315, 718, 526, 987,
479 692, 983, 595, 898, 282, 133, 439, 633,
480 534, 861, 269, 619, 677, 502, 375, 224,
481 806, 869, 417, 584, 612, 803, 58, 84,
482 788, 797, 38, 700, 751, 603, 652, 57,
483 240, 947, 350, 270, 333, 116, 736, 69,
484 74, 104, 767, 318, 735, 859, 357, 555,
485 411, 267, 712, 675, 532, 825, 496, 927,
486 942, 102, 46, 192, 114, 744, 138, 998,
487 72, 617, 134, 846, 166, 77, 900, 5,
488 303, 387, 400, 47, 729, 922, 222, 197,
489 351, 509, 524, 165, 485, 300, 944, 380,
490 625, 778, 685, 29, 589, 766, 161, 391,
491 423, 42, 734, 552, 215, 824, 908, 229,
492 89, 251, 199, 616, 78, 644, 242, 722,
493 25, 437, 732, 956, 275, 200, 970, 753,
494 791, 336, 556, 847, 703, 236, 715, 75,
495 863, 713, 785, 911, 786, 620, 551, 413,
496 39, 739, 820, 808, 764, 701, 819, 173,
497 989, 345, 690, 459, 60, 106, 887, 996,
498 365, 673, 968, 513, 18, 419, 550, 588,
499 435, 264, 789, 340, 659, 466, 356, 288,
500 56, 708, 557, 488, 760, 332, 402, 168,
501 202, 521, 757, 205, 706, 441, 773, 231,
502 583, 386, 678, 618, 815, 279, 87, 533,
503 61, 548, 92, 169, 694, 905, 198, 121,
504 410, 139, 657, 640, 743, 128, 458, 866,
505 501, 348, 155, 276, 101, 858, 323, 359,
506 };
507 }