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