Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 1 | /* |
Brian O'Connor | a09fe5b | 2017-08-03 21:12:30 -0700 | [diff] [blame] | 2 | * Copyright 2016-present Open Networking Foundation |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 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.config; |
| 17 | |
| 18 | |
Sithara Punnassery | 0620879 | 2017-02-10 16:25:29 -0800 | [diff] [blame] | 19 | import com.google.common.annotations.Beta; |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 20 | import com.google.common.collect.ImmutableSet; |
| 21 | |
Sithara Punnassery | 4b091dc | 2017-03-02 17:22:40 -0800 | [diff] [blame] | 22 | import org.onosproject.yang.model.ResourceId; |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 23 | |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 24 | import static com.google.common.base.Preconditions.checkNotNull; |
| 25 | |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 26 | import java.util.LinkedHashSet; |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 27 | import java.util.Set; |
| 28 | |
| 29 | /** |
| 30 | * Abstraction for Filters that can be used while traversing the dynamic config store. |
| 31 | * This abstraction allows to select entries of interest based on various criteria |
| 32 | * defined by this interface. |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 33 | * NOTE: Only criteria based on {@code ResourceId} are supported currently. |
| 34 | * This is a placeholder for a filter; Set of ResourceId becomes inefficient when |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 35 | * using a large number of filtering criteria; |
| 36 | */ |
Sithara Punnassery | 0620879 | 2017-02-10 16:25:29 -0800 | [diff] [blame] | 37 | @Beta |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 38 | public class Filter { |
| 39 | /** |
| 40 | * Traversal modes. |
| 41 | */ |
| 42 | public enum TraversalMode { |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 43 | |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 44 | /** |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 45 | * SUB_TREE : if the node points to a subtree, the entire subtree will |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 46 | * be traversed; if pointing to a leaf, just the leaf will be retrieved. |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 47 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 48 | SUB_TREE(-1), |
| 49 | /** |
| 50 | * NODE_ONLY : tree will not be traversed; will retrieve just the |
| 51 | * specific node, irrespective of it being a subtree root or a leaf node. |
| 52 | */ |
| 53 | NODE_ONLY(0), |
| 54 | /** |
| 55 | * GIVEN_DEPTH : as many levels of the subtree as indicated by depth |
| 56 | * field of filter that will be traversed; if depth is greater than |
| 57 | * the number of levels of children, the entire subtree will be |
| 58 | * traversed and end the traversal, without throwing any errors. |
| 59 | */ |
| 60 | GIVEN_DEPTH; |
| 61 | |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 62 | int val; |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 63 | TraversalMode() { |
| 64 | |
| 65 | } |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 66 | TraversalMode(int val) { |
| 67 | this.val = val; |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 68 | } |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 69 | int val() { |
| 70 | return val; |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 71 | } |
| 72 | } |
| 73 | |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 74 | /** |
| 75 | * Filtering criteria. |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 76 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 77 | private final Set<ResourceId> criteria; |
| 78 | /** |
| 79 | * Traversal mode; default is to read just the given node(NODE_ONLY). |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 80 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 81 | private final TraversalMode mode; |
| 82 | /** |
| 83 | * depth of traversal; default value is 0. |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 84 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 85 | private final int depth; |
| 86 | |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 87 | |
| 88 | /** |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 89 | * Creates a default Filter builder. |
| 90 | * |
| 91 | * @return Filter builder |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 92 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 93 | public static FilterBuilder builder() { |
| 94 | return new FilterBuilder(); |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 95 | } |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 96 | |
| 97 | /** |
| 98 | * Creates a Filter builder based on {@code start}. |
| 99 | * |
| 100 | * @param start Filter to initialize builder with |
| 101 | * @return Filter builder |
| 102 | * |
| 103 | */ |
| 104 | public static FilterBuilder builder(Filter start) { |
| 105 | return new FilterBuilder(start); |
| 106 | } |
| 107 | |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 108 | /** |
| 109 | * Creates a new Filter object. |
| 110 | * |
| 111 | * @param criteria set of filtering criteria |
| 112 | * @param mode traversal mode |
| 113 | * @param depth depth of traversal |
| 114 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 115 | protected Filter(Set<ResourceId> criteria, TraversalMode mode, int depth) { |
| 116 | this.criteria = ImmutableSet.copyOf(criteria); |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 117 | this.mode = mode; |
| 118 | this.depth = depth; |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | /** |
| 122 | * Returns the traversal mode. |
| 123 | * |
| 124 | *@return traversal mode |
| 125 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 126 | public TraversalMode mode() { |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 127 | return mode; |
| 128 | } |
| 129 | |
| 130 | /** |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 131 | * Returns the depth. |
| 132 | * |
| 133 | *@return depth |
| 134 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 135 | public int depth() { |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 136 | return depth; |
| 137 | } |
| 138 | |
| 139 | /** |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 140 | * Returns the criteria that are in place for a Filter. |
| 141 | * |
| 142 | * @return Set of ResourceId criteria |
| 143 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 144 | public Set<ResourceId> criteria() { |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 145 | return this.criteria; |
| 146 | } |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 147 | |
| 148 | /** |
| 149 | * Method to create a filter that include all entries rejected by the criteria. |
| 150 | * |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 151 | * @param original Filter object with a criteria set |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 152 | * @return Filter object with negated criteria set |
| 153 | * @throws InvalidFilterException if the received Filter object |
| 154 | * was null or if it had an empty criteria set |
| 155 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 156 | public static Filter negateFilter(Filter original) { |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 157 | throw new FailedException("Not yet implemented"); |
| 158 | } |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 159 | |
| 160 | /** |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 161 | * Returns if the Filter has an empty criteria set. |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 162 | * |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 163 | * @return {@code true} if criteria set is empty, {@code false} otherwise. |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 164 | */ |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 165 | public boolean isEmptyFilter() { |
Sithara Punnassery | 9306e6b | 2017-02-06 15:38:19 -0800 | [diff] [blame] | 166 | return criteria.isEmpty(); |
| 167 | } |
Yuta HIGUCHI | ac85ee1 | 2017-08-03 20:07:35 -0700 | [diff] [blame] | 168 | |
| 169 | public static final class FilterBuilder extends Builder<FilterBuilder> { |
| 170 | |
| 171 | private FilterBuilder(Filter start) { |
| 172 | super(start.criteria, start.mode, start.depth); |
| 173 | } |
| 174 | |
| 175 | private FilterBuilder() { |
| 176 | super(); |
| 177 | } |
| 178 | |
| 179 | public Filter build() { |
| 180 | return new Filter(criteria, mode, depth); |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | public abstract static class Builder<B extends Builder<B>> { |
| 185 | |
| 186 | protected Set<ResourceId> criteria; |
| 187 | protected TraversalMode mode; |
| 188 | protected int depth; |
| 189 | |
| 190 | protected Builder() { |
| 191 | this(ImmutableSet.of(), TraversalMode.NODE_ONLY, 0); |
| 192 | } |
| 193 | |
| 194 | protected Builder(Set<ResourceId> criteria, |
| 195 | TraversalMode mode, |
| 196 | int depth) { |
| 197 | this.criteria = new LinkedHashSet<>(criteria); |
| 198 | this.mode = checkNotNull(mode); |
| 199 | this.depth = depth; |
| 200 | } |
| 201 | |
| 202 | /** |
| 203 | * Adds a new ResourceId filtering criterion to a Filter object. |
| 204 | * If the same ResourceId is already part of the criteria |
| 205 | * for the object, it will not be added again, but will not throw any exceptions. |
| 206 | * This will not check for the validity of the ResourceId. |
| 207 | * |
| 208 | * @param add new criterion |
| 209 | * @return self |
| 210 | */ |
| 211 | public B addCriteria(ResourceId add) { |
| 212 | criteria.add(add); |
| 213 | return (B) this; |
| 214 | } |
| 215 | |
| 216 | /** |
| 217 | * Adds new ResourceId filtering criteria to a Filter object. |
| 218 | * If the same ResourceId is already part of the criteria |
| 219 | * for the object, it will not be added again, but will not throw any exceptions. |
| 220 | * This will not check for the validity of the ResourceId. |
| 221 | * |
| 222 | * @param addAll new criteria |
| 223 | * @return self |
| 224 | */ |
| 225 | public B addAllCriteria(Set<ResourceId> addAll) { |
| 226 | criteria.addAll(addAll); |
| 227 | return (B) this; |
| 228 | } |
| 229 | |
| 230 | /** |
| 231 | * Replaces ResourceId filtering criteria with the one specified. |
| 232 | * This will not check for the validity of the ResourceId. |
| 233 | * |
| 234 | * @param criteria new criteria |
| 235 | * @return self |
| 236 | */ |
| 237 | public B setCriteria(Set<ResourceId> criteria) { |
| 238 | this.criteria = (criteria); |
| 239 | return (B) this; |
| 240 | } |
| 241 | |
| 242 | /** |
| 243 | * Sets the traversal mode. |
| 244 | * |
| 245 | * @param mode traversal mode |
| 246 | * @return self |
| 247 | */ |
| 248 | public B mode(TraversalMode mode) { |
| 249 | this.mode = mode; |
| 250 | return (B) this; |
| 251 | } |
| 252 | |
| 253 | /** |
| 254 | * Sets the depth. |
| 255 | * |
| 256 | * @param depth of traversal |
| 257 | * @return self |
| 258 | */ |
| 259 | public B depth(int depth) { |
| 260 | this.depth = depth; |
| 261 | return (B) this; |
| 262 | } |
| 263 | /** |
| 264 | * Removes the given ResourceId filtering criterion from a Filter object. |
| 265 | * If the ResourceId was NOT already part of the criteria for |
| 266 | * the object, it will not be removed, but will not throw any exceptions. |
| 267 | * This will not check for the validity of the ResourceId. |
| 268 | * |
| 269 | * @param remove criterion to be removed |
| 270 | * @return self |
| 271 | */ |
| 272 | public B removeCriteria(ResourceId remove) { |
| 273 | criteria.remove(remove); |
| 274 | return (B) this; |
| 275 | } |
| 276 | |
| 277 | /** |
| 278 | * Removes the given ResourceId filtering criteria from a Filter object. |
| 279 | * If the ResourceId was NOT already part of the criteria for |
| 280 | * the object, it will not be removed, but will not throw any exceptions. |
| 281 | * This will not check for the validity of the ResourceId. |
| 282 | * |
| 283 | * @param removeAll criteria to be removed |
| 284 | * @return self |
| 285 | */ |
| 286 | public B removeAllCriteria(Set<ResourceId> removeAll) { |
| 287 | criteria.removeAll(removeAll); |
| 288 | return (B) this; |
| 289 | } |
| 290 | } |
Sithara Punnassery | ff11455 | 2017-01-10 11:40:55 -0800 | [diff] [blame] | 291 | } |