Committed by
Yuta HIGUCHI
Modify MPLS/VLAN query
- ONOS-3507 VlanQuery to return available VLAN IDs - ONOS-3508 MplsQuery to return available MPLS Labels - Advertise that VLAN and MPLS resources are available on OVS Change-Id: I74cd05393c8919b4823d0666348008adb93c9290
Showing
8 changed files
with
234 additions
and
45 deletions
| ... | @@ -16,6 +16,10 @@ | ... | @@ -16,6 +16,10 @@ |
| 16 | package org.onosproject.net.behaviour; | 16 | package org.onosproject.net.behaviour; |
| 17 | 17 | ||
| 18 | import com.google.common.annotations.Beta; | 18 | import com.google.common.annotations.Beta; |
| 19 | + | ||
| 20 | +import java.util.Set; | ||
| 21 | + | ||
| 22 | +import org.onlab.packet.MplsLabel; | ||
| 19 | import org.onosproject.net.PortNumber; | 23 | import org.onosproject.net.PortNumber; |
| 20 | import org.onosproject.net.driver.HandlerBehaviour; | 24 | import org.onosproject.net.driver.HandlerBehaviour; |
| 21 | 25 | ||
| ... | @@ -26,10 +30,11 @@ import org.onosproject.net.driver.HandlerBehaviour; | ... | @@ -26,10 +30,11 @@ import org.onosproject.net.driver.HandlerBehaviour; |
| 26 | public interface MplsQuery extends HandlerBehaviour { | 30 | public interface MplsQuery extends HandlerBehaviour { |
| 27 | 31 | ||
| 28 | /** | 32 | /** |
| 29 | - * Indicates if MPLS can be used at the port. | 33 | + * Returns set of MplsLabels which can be used at the port. |
| 30 | - | 34 | + * |
| 31 | - * @param port port to be checked for the capability | 35 | + * @param port to be checked for the available resources. |
| 32 | - * @return true if MPLS can be used at the port, false otherwise. | 36 | + * @return Set of MplsLabels which can be used at the port. |
| 33 | */ | 37 | */ |
| 34 | - boolean isEnabled(PortNumber port); | 38 | + Set<MplsLabel> queryMplsLabels(PortNumber port); |
| 39 | + | ||
| 35 | } | 40 | } | ... | ... |
| ... | @@ -16,6 +16,9 @@ | ... | @@ -16,6 +16,9 @@ |
| 16 | package org.onosproject.net.behaviour; | 16 | package org.onosproject.net.behaviour; |
| 17 | 17 | ||
| 18 | import com.google.common.annotations.Beta; | 18 | import com.google.common.annotations.Beta; |
| 19 | + | ||
| 20 | +import java.util.Set; | ||
| 21 | +import org.onlab.packet.VlanId; | ||
| 19 | import org.onosproject.net.PortNumber; | 22 | import org.onosproject.net.PortNumber; |
| 20 | import org.onosproject.net.driver.HandlerBehaviour; | 23 | import org.onosproject.net.driver.HandlerBehaviour; |
| 21 | 24 | ||
| ... | @@ -26,10 +29,11 @@ import org.onosproject.net.driver.HandlerBehaviour; | ... | @@ -26,10 +29,11 @@ import org.onosproject.net.driver.HandlerBehaviour; |
| 26 | public interface VlanQuery extends HandlerBehaviour { | 29 | public interface VlanQuery extends HandlerBehaviour { |
| 27 | 30 | ||
| 28 | /** | 31 | /** |
| 29 | - * Indicates if VLAN can be used at the port. | 32 | + * Returns set of VlanIds which can be used at the port. |
| 30 | * | 33 | * |
| 31 | - * @param port port to be checked for the capability | 34 | + * @param port to be checked for the available resources. |
| 32 | - * @return true if VLAN can be used at the port, false otherwise. | 35 | + * @return Set of VlanIds which can be used at the port. |
| 33 | */ | 36 | */ |
| 34 | - boolean isEnabled(PortNumber port); | 37 | + Set<VlanId> queryVlanIds(PortNumber port); |
| 38 | + | ||
| 35 | } | 39 | } | ... | ... |
| ... | @@ -15,6 +15,7 @@ | ... | @@ -15,6 +15,7 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.newresource.impl; | 16 | package org.onosproject.net.newresource.impl; |
| 17 | 17 | ||
| 18 | +import com.google.common.collect.ImmutableSet; | ||
| 18 | import com.google.common.collect.Lists; | 19 | import com.google.common.collect.Lists; |
| 19 | import org.onlab.packet.MplsLabel; | 20 | import org.onlab.packet.MplsLabel; |
| 20 | import org.onlab.packet.VlanId; | 21 | import org.onlab.packet.VlanId; |
| ... | @@ -44,6 +45,7 @@ import org.slf4j.LoggerFactory; | ... | @@ -44,6 +45,7 @@ import org.slf4j.LoggerFactory; |
| 44 | 45 | ||
| 45 | import java.util.Collections; | 46 | import java.util.Collections; |
| 46 | import java.util.List; | 47 | import java.util.List; |
| 48 | +import java.util.Set; | ||
| 47 | import java.util.SortedSet; | 49 | import java.util.SortedSet; |
| 48 | import java.util.concurrent.ExecutorService; | 50 | import java.util.concurrent.ExecutorService; |
| 49 | import java.util.stream.Collectors; | 51 | import java.util.stream.Collectors; |
| ... | @@ -58,16 +60,6 @@ final class ResourceDeviceListener implements DeviceListener { | ... | @@ -58,16 +60,6 @@ final class ResourceDeviceListener implements DeviceListener { |
| 58 | 60 | ||
| 59 | private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class); | 61 | private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class); |
| 60 | 62 | ||
| 61 | - private static final int MAX_VLAN_ID = VlanId.MAX_VLAN; | ||
| 62 | - private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans(); | ||
| 63 | - | ||
| 64 | - // Ref: http://www.iana.org/assignments/mpls-label-values/mpls-label-values.xhtml | ||
| 65 | - // Smallest non-reserved MPLS label | ||
| 66 | - private static final int MIN_UNRESERVED_LABEL = 0x10; | ||
| 67 | - // Max non-reserved MPLS label = 239 | ||
| 68 | - private static final int MAX_UNRESERVED_LABEL = 0xEF; | ||
| 69 | - private static final List<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels(); | ||
| 70 | - | ||
| 71 | private static final int TOTAL_ODU2_TRIBUTARY_SLOTS = 8; | 63 | private static final int TOTAL_ODU2_TRIBUTARY_SLOTS = 8; |
| 72 | private static final int TOTAL_ODU4_TRIBUTARY_SLOTS = 80; | 64 | private static final int TOTAL_ODU4_TRIBUTARY_SLOTS = 80; |
| 73 | private static final List<TributarySlot> ENTIRE_ODU2_TRIBUTARY_SLOTS = getEntireOdu2TributarySlots(); | 65 | private static final List<TributarySlot> ENTIRE_ODU2_TRIBUTARY_SLOTS = getEntireOdu2TributarySlots(); |
| ... | @@ -142,13 +134,19 @@ final class ResourceDeviceListener implements DeviceListener { | ... | @@ -142,13 +134,19 @@ final class ResourceDeviceListener implements DeviceListener { |
| 142 | adminService.registerResources(portPath); | 134 | adminService.registerResources(portPath); |
| 143 | 135 | ||
| 144 | // for VLAN IDs | 136 | // for VLAN IDs |
| 145 | - if (isVlanEnabled(device.id(), port.number())) { | 137 | + Set<VlanId> vlans = queryVlanIds(device.id(), port.number()); |
| 146 | - adminService.registerResources(Lists.transform(ENTIRE_VLAN_IDS, portPath::child)); | 138 | + if (!vlans.isEmpty()) { |
| 139 | + adminService.registerResources(vlans.stream() | ||
| 140 | + .map(portPath::child) | ||
| 141 | + .collect(Collectors.toList())); | ||
| 147 | } | 142 | } |
| 148 | 143 | ||
| 149 | // for MPLS labels | 144 | // for MPLS labels |
| 150 | - if (isMplsEnabled(device.id(), port.number())) { | 145 | + Set<MplsLabel> mplsLabels = queryMplsLabels(device.id(), port.number()); |
| 151 | - adminService.registerResources(Lists.transform(ENTIRE_MPLS_LABELS, portPath::child)); | 146 | + if (!mplsLabels.isEmpty()) { |
| 147 | + adminService.registerResources(mplsLabels.stream() | ||
| 148 | + .map(portPath::child) | ||
| 149 | + .collect(Collectors.toList())); | ||
| 152 | } | 150 | } |
| 153 | 151 | ||
| 154 | // for Lambdas | 152 | // for Lambdas |
| ... | @@ -215,61 +213,55 @@ final class ResourceDeviceListener implements DeviceListener { | ... | @@ -215,61 +213,55 @@ final class ResourceDeviceListener implements DeviceListener { |
| 215 | } | 213 | } |
| 216 | } | 214 | } |
| 217 | 215 | ||
| 218 | - private boolean isVlanEnabled(DeviceId device, PortNumber port) { | 216 | + private Set<VlanId> queryVlanIds(DeviceId device, PortNumber port) { |
| 219 | try { | 217 | try { |
| 220 | // DriverHandler does not provide a way to check if a | 218 | // DriverHandler does not provide a way to check if a |
| 221 | // behaviour is supported. | 219 | // behaviour is supported. |
| 222 | Driver driver = driverService.getDriver(device); | 220 | Driver driver = driverService.getDriver(device); |
| 223 | if (driver == null || !driver.hasBehaviour(VlanQuery.class)) { | 221 | if (driver == null || !driver.hasBehaviour(VlanQuery.class)) { |
| 224 | // device does not support this | 222 | // device does not support this |
| 225 | - return false; | 223 | + return ImmutableSet.of(); |
| 226 | } | 224 | } |
| 227 | 225 | ||
| 228 | DriverHandler handler = driverService.createHandler(device); | 226 | DriverHandler handler = driverService.createHandler(device); |
| 229 | if (handler == null) { | 227 | if (handler == null) { |
| 230 | - return false; | 228 | + return ImmutableSet.of(); |
| 231 | } | 229 | } |
| 232 | 230 | ||
| 233 | VlanQuery query = handler.behaviour(VlanQuery.class); | 231 | VlanQuery query = handler.behaviour(VlanQuery.class); |
| 234 | - return query != null && query.isEnabled(port); | 232 | + if (query == null) { |
| 233 | + return ImmutableSet.of(); | ||
| 234 | + } | ||
| 235 | + return query.queryVlanIds(port); | ||
| 235 | } catch (ItemNotFoundException e) { | 236 | } catch (ItemNotFoundException e) { |
| 236 | - return false; | 237 | + return ImmutableSet.of(); |
| 237 | } | 238 | } |
| 238 | } | 239 | } |
| 239 | 240 | ||
| 240 | - private boolean isMplsEnabled(DeviceId device, PortNumber port) { | 241 | + private Set<MplsLabel> queryMplsLabels(DeviceId device, PortNumber port) { |
| 241 | try { | 242 | try { |
| 242 | // DriverHandler does not provide a way to check if a | 243 | // DriverHandler does not provide a way to check if a |
| 243 | // behaviour is supported. | 244 | // behaviour is supported. |
| 244 | Driver driver = driverService.getDriver(device); | 245 | Driver driver = driverService.getDriver(device); |
| 245 | if (driver == null || !driver.hasBehaviour(MplsQuery.class)) { | 246 | if (driver == null || !driver.hasBehaviour(MplsQuery.class)) { |
| 246 | // device does not support this | 247 | // device does not support this |
| 247 | - return false; | 248 | + return ImmutableSet.of(); |
| 248 | } | 249 | } |
| 249 | DriverHandler handler = driverService.createHandler(device); | 250 | DriverHandler handler = driverService.createHandler(device); |
| 250 | if (handler == null) { | 251 | if (handler == null) { |
| 251 | - return false; | 252 | + return ImmutableSet.of(); |
| 252 | } | 253 | } |
| 253 | 254 | ||
| 254 | MplsQuery query = handler.behaviour(MplsQuery.class); | 255 | MplsQuery query = handler.behaviour(MplsQuery.class); |
| 255 | - return query != null && query.isEnabled(port); | 256 | + if (query == null) { |
| 257 | + return ImmutableSet.of(); | ||
| 258 | + } | ||
| 259 | + return query.queryMplsLabels(port); | ||
| 256 | } catch (ItemNotFoundException e) { | 260 | } catch (ItemNotFoundException e) { |
| 257 | - return false; | 261 | + return ImmutableSet.of(); |
| 258 | } | 262 | } |
| 259 | } | 263 | } |
| 260 | 264 | ||
| 261 | - private static List<VlanId> getEntireVlans() { | ||
| 262 | - return IntStream.range(0, MAX_VLAN_ID) | ||
| 263 | - .mapToObj(x -> VlanId.vlanId((short) x)) | ||
| 264 | - .collect(Collectors.toList()); | ||
| 265 | - } | ||
| 266 | - | ||
| 267 | - private static List<MplsLabel> getEntireMplsLabels() { | ||
| 268 | - return IntStream.range(MIN_UNRESERVED_LABEL, MAX_UNRESERVED_LABEL + 1) | ||
| 269 | - .mapToObj(MplsLabel::mplsLabel) | ||
| 270 | - .collect(Collectors.toList()); | ||
| 271 | - } | ||
| 272 | - | ||
| 273 | private static List<TributarySlot> getEntireOdu2TributarySlots() { | 265 | private static List<TributarySlot> getEntireOdu2TributarySlots() { |
| 274 | return IntStream.rangeClosed(1, TOTAL_ODU2_TRIBUTARY_SLOTS) | 266 | return IntStream.rangeClosed(1, TOTAL_ODU2_TRIBUTARY_SLOTS) |
| 275 | .mapToObj(TributarySlot::of) | 267 | .mapToObj(TributarySlot::of) | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.driver.query; | ||
| 17 | + | ||
| 18 | +import java.util.Set; | ||
| 19 | +import java.util.stream.IntStream; | ||
| 20 | + | ||
| 21 | +import org.onlab.packet.MplsLabel; | ||
| 22 | +import org.onlab.util.GuavaCollectors; | ||
| 23 | +import org.onosproject.net.PortNumber; | ||
| 24 | +import org.onosproject.net.behaviour.MplsQuery; | ||
| 25 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * Driver which always responds that all MPLS Labels are available for the Device. | ||
| 29 | + */ | ||
| 30 | +public class FullMplsAvailable | ||
| 31 | + extends AbstractHandlerBehaviour | ||
| 32 | + implements MplsQuery { | ||
| 33 | + | ||
| 34 | + // Ref: http://www.iana.org/assignments/mpls-label-values/mpls-label-values.xhtml | ||
| 35 | + // Smallest non-reserved MPLS label | ||
| 36 | + private static final int MIN_UNRESERVED_LABEL = 0x10; | ||
| 37 | + // Max non-reserved MPLS label = 239 | ||
| 38 | + private static final int MAX_UNRESERVED_LABEL = 0xEF; | ||
| 39 | + private static final Set<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels(); | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public Set<MplsLabel> queryMplsLabels(PortNumber port) { | ||
| 44 | + return ENTIRE_MPLS_LABELS; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + private static Set<MplsLabel> getEntireMplsLabels() { | ||
| 48 | + return IntStream.range(MIN_UNRESERVED_LABEL, MAX_UNRESERVED_LABEL + 1) | ||
| 49 | + .mapToObj(MplsLabel::mplsLabel) | ||
| 50 | + .collect(GuavaCollectors.toImmutableSet()); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.driver.query; | ||
| 17 | + | ||
| 18 | +import java.util.Set; | ||
| 19 | +import java.util.stream.IntStream; | ||
| 20 | + | ||
| 21 | +import org.onlab.packet.VlanId; | ||
| 22 | +import org.onlab.util.GuavaCollectors; | ||
| 23 | +import org.onosproject.net.PortNumber; | ||
| 24 | +import org.onosproject.net.behaviour.VlanQuery; | ||
| 25 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
| 26 | + | ||
| 27 | +import com.google.common.annotations.Beta; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * Driver which always responds that all VLAN IDs are available for the Device. | ||
| 31 | + */ | ||
| 32 | +@Beta | ||
| 33 | +public class FullVlanAvailable | ||
| 34 | + extends AbstractHandlerBehaviour | ||
| 35 | + implements VlanQuery { | ||
| 36 | + | ||
| 37 | + private static final int MAX_VLAN_ID = VlanId.MAX_VLAN; | ||
| 38 | + private static final Set<VlanId> ENTIRE_VLAN = getEntireVlans(); | ||
| 39 | + | ||
| 40 | + @Override | ||
| 41 | + public Set<VlanId> queryVlanIds(PortNumber port) { | ||
| 42 | + return ENTIRE_VLAN; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + private static Set<VlanId> getEntireVlans() { | ||
| 46 | + return IntStream.range(0, MAX_VLAN_ID) | ||
| 47 | + .mapToObj(x -> VlanId.vlanId((short) x)) | ||
| 48 | + .collect(GuavaCollectors.toImmutableSet()); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * Implementations of the query driver behaviours. | ||
| 19 | + */ | ||
| 20 | +package org.onosproject.driver.query; |
| ... | @@ -40,6 +40,10 @@ | ... | @@ -40,6 +40,10 @@ |
| 40 | impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" /> | 40 | impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" /> |
| 41 | <behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver" | 41 | <behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver" |
| 42 | impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" /> | 42 | impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" /> |
| 43 | + <behaviour api="org.onosproject.net.behaviour.VlanQuery" | ||
| 44 | + impl="org.onosproject.driver.query.FullVlanAvailable" /> | ||
| 45 | + <behaviour api="org.onosproject.net.behaviour.MplsQuery" | ||
| 46 | + impl="org.onosproject.driver.query.FullMplsAvailable" /> | ||
| 43 | </driver> | 47 | </driver> |
| 44 | <!--This driver is for simulated NETCONF devices through of-config tool on top og OVSDB--> | 48 | <!--This driver is for simulated NETCONF devices through of-config tool on top og OVSDB--> |
| 45 | <driver name="ovs-netconf" extends="default" | 49 | <driver name="ovs-netconf" extends="default" | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onlab.util; | ||
| 17 | + | ||
| 18 | +import java.util.stream.Collector; | ||
| 19 | +import java.util.stream.Collector.Characteristics; | ||
| 20 | + | ||
| 21 | +import com.google.common.collect.ImmutableList; | ||
| 22 | +import com.google.common.collect.ImmutableSet; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * Implementations of {@link Collector} that implement various useful reduction | ||
| 26 | + * operations, such as accumulating elements into Guava collections. | ||
| 27 | + */ | ||
| 28 | +public final class GuavaCollectors { | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * Returns a {@code Collector} that accumulates the input elements into a | ||
| 32 | + * new ImmutableSet. | ||
| 33 | + * | ||
| 34 | + * @return a {@code Collector} which collects all the input elements into a | ||
| 35 | + * {@code ImmutableSet} | ||
| 36 | + */ | ||
| 37 | + public static <T> Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>> toImmutableSet() { | ||
| 38 | + return Collector.of(ImmutableSet.Builder<T>::new, | ||
| 39 | + ImmutableSet.Builder<T>::add, | ||
| 40 | + (s, r) -> s.addAll(r.build()), | ||
| 41 | + ImmutableSet.Builder<T>::build, | ||
| 42 | + Characteristics.UNORDERED); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Returns a {@code Collector} that accumulates the input elements into a | ||
| 47 | + * new ImmutableList. | ||
| 48 | + * | ||
| 49 | + * @return a {@code Collector} which collects all the input elements into a | ||
| 50 | + * {@code ImmutableList}, in encounter order | ||
| 51 | + */ | ||
| 52 | + public static <T> Collector<T, ImmutableList.Builder<T>, ImmutableList<T>> toImmutableList() { | ||
| 53 | + return Collector.of(ImmutableList.Builder<T>::new, | ||
| 54 | + ImmutableList.Builder<T>::add, | ||
| 55 | + (s, r) -> s.addAll(r.build()), | ||
| 56 | + ImmutableList.Builder<T>::build); | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + private GuavaCollectors() {} | ||
| 60 | +} |
-
Please register or login to post a comment