|
1 | 1 | /*
|
2 |
| - * Copyright 2012-2023 the original author or authors. |
| 2 | + * Copyright 2012-2025 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
43 | 43 | */
|
44 | 44 | abstract class IndexedElementsBinder<T> extends AggregateBinder<T> {
|
45 | 45 |
|
46 |
| - private static final String INDEX_ZERO = "[0]"; |
| 46 | + private static final String[] INDEXES; |
| 47 | + static { |
| 48 | + INDEXES = new String[10]; |
| 49 | + for (int i = 0; i < INDEXES.length; i++) { |
| 50 | + INDEXES[i] = "[" + i + "]"; |
| 51 | + } |
| 52 | + } |
47 | 53 |
|
48 | 54 | IndexedElementsBinder(Context context) {
|
49 | 55 | super(context);
|
@@ -100,15 +106,36 @@ private void bindValue(Bindable<?> target, Collection<Object> collection, Resolv
|
100 | 106 |
|
101 | 107 | private void bindIndexed(ConfigurationPropertySource source, ConfigurationPropertyName root,
|
102 | 108 | AggregateElementBinder elementBinder, IndexedCollectionSupplier collection, ResolvableType elementType) {
|
103 |
| - MultiValueMap<String, ConfigurationPropertyName> knownIndexedChildren = getKnownIndexedChildren(source, root); |
| 109 | + int firstUnboundIndex = 0; |
| 110 | + boolean hasBindingGap = false; |
104 | 111 | for (int i = 0; i < Integer.MAX_VALUE; i++) {
|
105 |
| - ConfigurationPropertyName name = root.append((i != 0) ? "[" + i + "]" : INDEX_ZERO); |
| 112 | + ConfigurationPropertyName name = appendIndex(root, i); |
106 | 113 | Object value = elementBinder.bind(name, Bindable.of(elementType), source);
|
107 |
| - if (value == null) { |
| 114 | + if (value != null) { |
| 115 | + collection.get().add(value); |
| 116 | + hasBindingGap = hasBindingGap || firstUnboundIndex > 0; |
| 117 | + continue; |
| 118 | + } |
| 119 | + firstUnboundIndex = (firstUnboundIndex <= 0) ? i : firstUnboundIndex; |
| 120 | + if (i - firstUnboundIndex > 10) { |
108 | 121 | break;
|
109 | 122 | }
|
| 123 | + } |
| 124 | + if (hasBindingGap) { |
| 125 | + assertNoUnboundChildren(source, root, firstUnboundIndex); |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + private ConfigurationPropertyName appendIndex(ConfigurationPropertyName root, int i) { |
| 130 | + return root.append((i < INDEXES.length) ? INDEXES[i] : "[" + i + "]"); |
| 131 | + } |
| 132 | + |
| 133 | + private void assertNoUnboundChildren(ConfigurationPropertySource source, ConfigurationPropertyName root, |
| 134 | + int firstUnboundIndex) { |
| 135 | + MultiValueMap<String, ConfigurationPropertyName> knownIndexedChildren = getKnownIndexedChildren(source, root); |
| 136 | + for (int i = 0; i < firstUnboundIndex; i++) { |
| 137 | + ConfigurationPropertyName name = appendIndex(root, i); |
110 | 138 | knownIndexedChildren.remove(name.getLastElement(Form.UNIFORM));
|
111 |
| - collection.get().add(value); |
112 | 139 | }
|
113 | 140 | assertNoUnboundChildren(source, knownIndexedChildren);
|
114 | 141 | }
|
|
0 commit comments