blob: dcdb008b52aa36866ede297a1060c65c8d16213f [file] [log] [blame]
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -07001/*
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 */
Thomas Vachuskad24aa7f2015-05-14 18:37:54 -070016package org.onosproject.incubator.net.config;
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070017
18import com.fasterxml.jackson.databind.ObjectMapper;
Brian O'Connorce2d8b52015-07-29 16:24:13 -070019import com.fasterxml.jackson.databind.node.ArrayNode;
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070020import com.fasterxml.jackson.databind.node.ObjectNode;
Thomas Vachuskae2b7e7e2015-05-20 11:11:31 -070021import com.google.common.annotations.Beta;
Brian O'Connorce2d8b52015-07-29 16:24:13 -070022import com.google.common.collect.Lists;
23
24import java.util.Collection;
25import java.util.List;
26import java.util.function.Function;
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070027
28import static com.google.common.base.Preconditions.checkNotNull;
29
30/**
31 * Base abstraction of a configuration facade for a specific subject. Derived
Thomas Vachuska96d55b12015-05-11 08:52:03 -070032 * classes should keep all state in the specified JSON tree as that is the
33 * only state that will be distributed or persisted; this class is merely
34 * a facade for interacting with a particular facet of configuration on a
35 * given subject.
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070036 *
37 * @param <S> type of subject
38 */
Thomas Vachuskae2b7e7e2015-05-20 11:11:31 -070039@Beta
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070040public abstract class Config<S> {
41
Thomas Vachuska96d55b12015-05-11 08:52:03 -070042 protected S subject;
43 protected String key;
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070044 protected ObjectNode node;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070045 protected ObjectMapper mapper;
46 protected ConfigApplyDelegate delegate;
47
48 /**
49 * Initializes the configuration behaviour with necessary context.
50 *
51 * @param subject configuration subject
52 * @param key configuration key
53 * @param node JSON object node where configuration data is stored
54 * @param mapper JSON object mapper
55 * @param delegate delegate context
56 */
57 public void init(S subject, String key, ObjectNode node, ObjectMapper mapper,
58 ConfigApplyDelegate delegate) {
59 this.subject = checkNotNull(subject);
60 this.key = key;
61 this.node = checkNotNull(node);
62 this.mapper = checkNotNull(mapper);
63 this.delegate = checkNotNull(delegate);
64 }
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070065
66 /**
67 * Returns the specific subject to which this configuration pertains.
68 *
69 * @return configuration subject
70 */
Thomas Vachuska96d55b12015-05-11 08:52:03 -070071 public S subject() {
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070072 return subject;
73 }
74
75 /**
Thomas Vachuska96d55b12015-05-11 08:52:03 -070076 * Returns the configuration key. This is primarily aimed for use in
77 * composite JSON trees in external representations and has no bearing on
78 * the internal behaviours.
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070079 *
Thomas Vachuska96d55b12015-05-11 08:52:03 -070080 * @return configuration key
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070081 */
Thomas Vachuska96d55b12015-05-11 08:52:03 -070082 public String key() {
83 return key;
84 }
85
86 /**
87 * Returns the JSON node that contains the configuration data.
88 *
89 * @return JSON node backing the configuration
90 */
91 public ObjectNode node() {
92 return node;
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -070093 }
94
95 /**
96 * Applies any configuration changes made via this configuration.
97 */
98 public void apply() {
99 delegate.onApply(this);
100 }
101
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700102
103 // Miscellaneous helpers for interacting with JSON
104
105 /**
106 * Gets the specified property as a string.
107 *
108 * @param name property name
109 * @param defaultValue default value if property not set
110 * @return property value or default value
111 */
112 protected String get(String name, String defaultValue) {
113 return node.path(name).asText(defaultValue);
114 }
115
116 /**
117 * Sets the specified property as a string or clears it if null value given.
118 *
119 * @param name property name
120 * @param value new value or null to clear the property
121 * @return self
122 */
123 protected Config<S> setOrClear(String name, String value) {
124 if (value != null) {
125 node.put(name, value);
126 } else {
127 node.remove(name);
128 }
129 return this;
130 }
131
132 /**
133 * Gets the specified property as a boolean.
134 *
135 * @param name property name
136 * @param defaultValue default value if property not set
137 * @return property value or default value
138 */
139 protected boolean get(String name, boolean defaultValue) {
140 return node.path(name).asBoolean(defaultValue);
141 }
142
143 /**
144 * Sets the specified property as a boolean or clears it if null value given.
145 *
146 * @param name property name
147 * @param value new value or null to clear the property
148 * @return self
149 */
150 protected Config<S> setOrClear(String name, Boolean value) {
151 if (value != null) {
152 node.put(name, value.booleanValue());
153 } else {
154 node.remove(name);
155 }
156 return this;
157 }
158
159 /**
Jonathan Hart111b42b2015-07-14 13:28:05 -0700160 * Gets the specified property as an integer.
161 *
162 * @param name property name
163 * @param defaultValue default value if property not set
164 * @return property value or default value
165 */
166 protected int get(String name, int defaultValue) {
167 return node.path(name).asInt(defaultValue);
168 }
169
170 /**
171 * Sets the specified property as an integer or clears it if null value given.
172 *
173 * @param name property name
174 * @param value new value or null to clear the property
175 * @return self
176 */
177 protected Config<S> setOrClear(String name, Integer value) {
178 if (value != null) {
179 node.put(name, value.intValue());
180 } else {
181 node.remove(name);
182 }
183 return this;
184 }
185
186 /**
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700187 * Gets the specified property as a long.
188 *
189 * @param name property name
190 * @param defaultValue default value if property not set
191 * @return property value or default value
192 */
193 protected long get(String name, long defaultValue) {
194 return node.path(name).asLong(defaultValue);
195 }
196
197 /**
198 * Sets the specified property as a long or clears it if null value given.
199 *
200 * @param name property name
201 * @param value new value or null to clear the property
202 * @return self
203 */
204 protected Config<S> setOrClear(String name, Long value) {
205 if (value != null) {
206 node.put(name, value.longValue());
207 } else {
208 node.remove(name);
209 }
210 return this;
211 }
212
213 /**
214 * Gets the specified property as a double.
215 *
216 * @param name property name
217 * @param defaultValue default value if property not set
218 * @return property value or default value
219 */
220 protected double get(String name, double defaultValue) {
221 return node.path(name).asDouble(defaultValue);
222 }
223
224 /**
225 * Sets the specified property as a double or clears it if null value given.
226 *
227 * @param name property name
228 * @param value new value or null to clear the property
229 * @return self
230 */
231 protected Config<S> setOrClear(String name, Double value) {
232 if (value != null) {
233 node.put(name, value.doubleValue());
234 } else {
235 node.remove(name);
236 }
237 return this;
238 }
239
240 /**
241 * Gets the specified property as an enum.
242 *
243 * @param name property name
244 * @param defaultValue default value if property not set
245 * @param enumClass the enum class
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700246 * @param <E> type of enum
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700247 * @return property value or default value
248 */
249 protected <E extends Enum<E>> E get(String name, E defaultValue, Class<E> enumClass) {
250 return Enum.valueOf(enumClass, node.path(name).asText(defaultValue.toString()));
251 }
252
253 /**
254 * Sets the specified property as a double or clears it if null value given.
255 *
256 * @param name property name
257 * @param value new value or null to clear the property
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700258 * @param <E> type of enum
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700259 * @return self
260 */
261 protected <E extends Enum> Config<S> setOrClear(String name, E value) {
262 if (value != null) {
263 node.put(name, value.toString());
264 } else {
265 node.remove(name);
266 }
267 return this;
268 }
Jonathan Hart111b42b2015-07-14 13:28:05 -0700269
Brian O'Connorce2d8b52015-07-29 16:24:13 -0700270 /**
271 * Gets the specified array property as a list of items.
272 *
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700273 * @param name property name
Brian O'Connorce2d8b52015-07-29 16:24:13 -0700274 * @param function mapper from string to item
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700275 * @param <T> type of item
Brian O'Connorce2d8b52015-07-29 16:24:13 -0700276 * @return list of items
277 */
278 protected <T> List<T> getList(String name, Function<String, T> function) {
279 List<T> list = Lists.newArrayList();
280 ArrayNode arrayNode = (ArrayNode) node.path(name);
281 arrayNode.forEach(i -> list.add(function.apply(i.asText())));
282 return list;
283 }
284
285 /**
286 * Sets the specified property as an array of items in a given collection or
287 * clears it if null is given.
288 *
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700289 * @param name propertyName
Brian O'Connorce2d8b52015-07-29 16:24:13 -0700290 * @param collection collection of items
Thomas Vachuskad894b5d2015-07-30 11:59:07 -0700291 * @param <T> type of items
Brian O'Connorce2d8b52015-07-29 16:24:13 -0700292 * @return self
293 */
294 protected <T> Config<S> setOrClear(String name, Collection<T> collection) {
295 if (collection == null) {
296 node.remove(name);
297 } else {
298 ArrayNode arrayNode = mapper.createArrayNode();
299 collection.forEach(i -> arrayNode.add(i.toString()));
300 node.set(name, arrayNode);
301 }
302 return this;
303 }
304
Thomas Vachuskaf0e1fae2015-04-24 00:51:51 -0700305}