blob: 561fa763177536611b53306dae73954ad80d85e3 [file] [log] [blame]
Simon Hunt0af1ec32015-07-24 12:17:55 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Simon Hunt0af1ec32015-07-24 12:17:55 -07003 *
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.
Simon Hunt0af1ec32015-07-24 12:17:55 -070015 */
16
17package org.onosproject.ui.topo;
18
Simon Hunt629b99e2015-07-27 17:38:33 -070019import com.google.common.collect.Sets;
20
Simon Huntcd150272015-11-04 14:09:36 -080021import java.text.NumberFormat;
Simon Hunt0af1ec32015-07-24 12:17:55 -070022import java.util.ArrayList;
23import java.util.List;
Simon Hunt629b99e2015-07-27 17:38:33 -070024import java.util.Set;
Simon Hunt0af1ec32015-07-24 12:17:55 -070025
26/**
27 * Models a panel displayed on the Topology View.
28 */
29public class PropertyPanel {
30
Simon Huntcd150272015-11-04 14:09:36 -080031 private static final NumberFormat NF = NumberFormat.getInstance();
Simon Hunt00a27ff2015-07-28 18:53:40 -070032
Simon Hunt0af1ec32015-07-24 12:17:55 -070033 private String title;
34 private String typeId;
Simon Huntb745ca62015-07-28 15:37:11 -070035 private String id;
Simon Hunt10618f62017-06-15 19:30:52 -070036 private String navPath;
Simon Hunt0af1ec32015-07-24 12:17:55 -070037 private List<Prop> properties = new ArrayList<>();
Simon Hunt8d22c4b2015-08-06 16:24:43 -070038 private List<ButtonId> buttons = new ArrayList<>();
Simon Hunt0af1ec32015-07-24 12:17:55 -070039
Simon Hunt629b99e2015-07-27 17:38:33 -070040 /**
41 * Constructs a property panel model with the given title and
42 * type identifier (icon to display).
43 *
Simon Hunt10618f62017-06-15 19:30:52 -070044 * @param title title text
Simon Hunt629b99e2015-07-27 17:38:33 -070045 * @param typeId type (icon) ID
46 */
Simon Hunt0af1ec32015-07-24 12:17:55 -070047 public PropertyPanel(String title, String typeId) {
48 this.title = title;
49 this.typeId = typeId;
50 }
51
Simon Hunt629b99e2015-07-27 17:38:33 -070052 /**
Simon Huntcd150272015-11-04 14:09:36 -080053 * Returns a number formatter to use for formatting integer and long
54 * property values.
55 * <p>
56 * This default implementation uses a formatter for the default
57 * locale. For example:
58 * <pre>
59 * Locale.ENGLISH : 1000 -&gt; "1,000"
60 * Locale.FRENCH : 1000 -&gt; "1 000"
61 * Locale.GERMAN : 1000 -&gt; "1.000"
62 * </pre>
63 *
64 * @return the number formatter
65 */
66 protected NumberFormat formatter() {
67 return NF;
68 }
69
70 /**
Simon Hunt10618f62017-06-15 19:30:52 -070071 * Adds a navigation path field to the panel data, to be included in
72 * the returned JSON data to the client. This is typically used to
73 * configure the topology view with the appropriate navigation path for
74 * a hot-link to some other view.
75 *
76 * @param navPath the navigation path
77 * @return self for chaining
78 */
79 public PropertyPanel navPath(String navPath) {
80 this.navPath = navPath;
81 return this;
82 }
83
84 /**
Simon Huntb745ca62015-07-28 15:37:11 -070085 * Adds an ID field to the panel data, to be included in
86 * the returned JSON data to the client.
87 *
88 * @param id the identifier
89 * @return self, for chaining
90 */
91 public PropertyPanel id(String id) {
92 this.id = id;
93 return this;
94 }
95
Simon Hunt00a27ff2015-07-28 18:53:40 -070096 /**
97 * Adds a property to the panel data.
98 *
Simon Hunt10618f62017-06-15 19:30:52 -070099 * @param key property key
Simon Hunt879ce452017-08-10 23:32:00 -0700100 * @param label property label (localized)
Simon Hunt00a27ff2015-07-28 18:53:40 -0700101 * @param value property value
102 * @return self, for chaining
103 */
Simon Hunt879ce452017-08-10 23:32:00 -0700104 public PropertyPanel addProp(String key, String label, String value) {
105 properties.add(new Prop(key, label, value));
Simon Hunt00a27ff2015-07-28 18:53:40 -0700106 return this;
107 }
108
109 /**
110 * Adds a property to the panel data, using a decimal formatter.
111 *
Simon Hunt10618f62017-06-15 19:30:52 -0700112 * @param key property key
Simon Hunt879ce452017-08-10 23:32:00 -0700113 * @param label property label (localized)
Simon Hunt00a27ff2015-07-28 18:53:40 -0700114 * @param value property value
115 * @return self, for chaining
116 */
Simon Hunt879ce452017-08-10 23:32:00 -0700117 public PropertyPanel addProp(String key, String label, int value) {
118 properties.add(new Prop(key, label, formatter().format(value)));
Simon Hunt00a27ff2015-07-28 18:53:40 -0700119 return this;
120 }
121
122 /**
123 * Adds a property to the panel data, using a decimal formatter.
124 *
Simon Hunt10618f62017-06-15 19:30:52 -0700125 * @param key property key
Simon Hunt879ce452017-08-10 23:32:00 -0700126 * @param label property label (localized)
Simon Hunt00a27ff2015-07-28 18:53:40 -0700127 * @param value property value
128 * @return self, for chaining
129 */
Simon Hunt879ce452017-08-10 23:32:00 -0700130 public PropertyPanel addProp(String key, String label, long value) {
131 properties.add(new Prop(key, label, formatter().format(value)));
Simon Hunt00a27ff2015-07-28 18:53:40 -0700132 return this;
133 }
134
135 /**
136 * Adds a property to the panel data. Note that the value's
137 * {@link Object#toString toString()} method is used to convert the
138 * value to a string.
139 *
Simon Hunt10618f62017-06-15 19:30:52 -0700140 * @param key property key
Simon Hunt879ce452017-08-10 23:32:00 -0700141 * @param label property label (localized)
Simon Hunt00a27ff2015-07-28 18:53:40 -0700142 * @param value property value
143 * @return self, for chaining
144 */
Simon Hunt879ce452017-08-10 23:32:00 -0700145 public PropertyPanel addProp(String key, String label, Object value) {
146 properties.add(new Prop(key, label, value.toString()));
Simon Hunt00a27ff2015-07-28 18:53:40 -0700147 return this;
148 }
149
150 /**
151 * Adds a property to the panel data. Note that the value's
152 * {@link Object#toString toString()} method is used to convert the
153 * value to a string, from which the characters defined in the given
154 * regular expression string are stripped.
155 *
Simon Hunt10618f62017-06-15 19:30:52 -0700156 * @param key property key
Simon Hunt879ce452017-08-10 23:32:00 -0700157 * @param label property label (localized)
158 * @param value property value
159 * @param reStrip regexp characters to strip from value string
160 * @return self, for chaining
161 */
162 public PropertyPanel addProp(String key, String label,
163 Object value, String reStrip) {
164 String val = value.toString().replaceAll(reStrip, "");
165 properties.add(new Prop(key, label, val));
166 return this;
167 }
168
169 /*
170 * The following degenerate forms of addProp(...) for backward compatibility.
171 */
172
173 /**
174 * Adds a property to the panel data.
175 * Note that the key is used as the label.
176 *
177 * @param key property key (also used as display label)
178 * @param value property value
179 * @return self, for chaining
180 * @see #addProp(String, String, String)
181 */
182 public PropertyPanel addProp(String key, String value) {
183 return addProp(key, key, value);
184 }
185
186 /**
187 * Adds a property to the panel data, using a decimal formatter.
188 * Note that the key is used as the label.
189 *
190 * @param key property key (also used as display label)
191 * @param value property value
192 * @return self, for chaining
193 */
194 public PropertyPanel addProp(String key, int value) {
195 return addProp(key, key, value);
196 }
197
198 /**
199 * Adds a property to the panel data, using a decimal formatter.
200 * Note that the key is used as the label.
201 *
202 * @param key property key (also used as display label)
203 * @param value property value
204 * @return self, for chaining
205 */
206 public PropertyPanel addProp(String key, long value) {
207 return addProp(key, key, value);
208 }
209
210 /**
211 * Adds a property to the panel data. Note that the value's
212 * {@link Object#toString toString()} method is used to convert the
213 * value to a string.
214 * Note also that the key is used as the label.
215 *
216 * @param key property key (also used as display label)
217 * @param value property value
218 * @return self, for chaining
219 */
220 public PropertyPanel addProp(String key, Object value) {
221 return addProp(key, key, value);
222 }
223
224 /**
225 * Adds a property to the panel data. Note that the value's
226 * {@link Object#toString toString()} method is used to convert the
227 * value to a string, from which the characters defined in the given
228 * regular expression string are stripped.
229 * Note also that the key is used as the label.
230 *
231 * @param key property key (also used as display label)
Simon Hunt10618f62017-06-15 19:30:52 -0700232 * @param value property value
Simon Hunt00a27ff2015-07-28 18:53:40 -0700233 * @param reStrip regexp characters to strip from value string
234 * @return self, for chaining
235 */
236 public PropertyPanel addProp(String key, Object value, String reStrip) {
Simon Hunt879ce452017-08-10 23:32:00 -0700237 return addProp(key, key, value, reStrip);
Simon Hunt00a27ff2015-07-28 18:53:40 -0700238 }
239
240 /**
241 * Adds a separator to the panel data.
242 *
243 * @return self, for chaining
244 */
245 public PropertyPanel addSeparator() {
246 properties.add(new Separator());
247 return this;
248 }
Simon Huntb745ca62015-07-28 15:37:11 -0700249
250 /**
Simon Hunt629b99e2015-07-27 17:38:33 -0700251 * Returns the title text.
252 *
253 * @return title text
254 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700255 public String title() {
256 return title;
257 }
258
Simon Hunt629b99e2015-07-27 17:38:33 -0700259 /**
260 * Returns the type identifier.
261 *
262 * @return type identifier
263 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700264 public String typeId() {
265 return typeId;
266 }
267
Simon Hunt629b99e2015-07-27 17:38:33 -0700268 /**
Simon Hunt10618f62017-06-15 19:30:52 -0700269 * Returns the navigation path.
270 *
271 * @return the navigation path
272 */
273 public String navPath() {
274 return navPath;
275 }
276
277 /**
Simon Huntb745ca62015-07-28 15:37:11 -0700278 * Returns the internal ID.
279 *
280 * @return the ID
281 */
282 public String id() {
283 return id;
284 }
285
286 /**
Simon Hunt629b99e2015-07-27 17:38:33 -0700287 * Returns the list of properties to be displayed.
288 *
289 * @return the property list
290 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700291 // TODO: consider protecting this?
292 public List<Prop> properties() {
293 return properties;
294 }
295
Simon Huntfb940112015-07-29 18:36:35 -0700296 /**
297 * Returns the list of button descriptors.
298 *
299 * @return the button list
300 */
301 // TODO: consider protecting this?
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700302 public List<ButtonId> buttons() {
Simon Huntfb940112015-07-29 18:36:35 -0700303 return buttons;
304 }
305
Simon Hunt629b99e2015-07-27 17:38:33 -0700306 // == MUTATORS
307
308 /**
309 * Sets the title text.
310 *
311 * @param title title text
312 * @return self, for chaining
313 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700314 public PropertyPanel title(String title) {
315 this.title = title;
316 return this;
317 }
318
Simon Hunt629b99e2015-07-27 17:38:33 -0700319 /**
320 * Sets the type identifier (icon ID).
321 *
322 * @param typeId type identifier
323 * @return self, for chaining
324 */
325 public PropertyPanel typeId(String typeId) {
326 this.typeId = typeId;
327 return this;
328 }
Simon Hunt0af1ec32015-07-24 12:17:55 -0700329
Simon Hunt629b99e2015-07-27 17:38:33 -0700330 /**
331 * Removes properties with the given keys from the list.
332 *
333 * @param keys keys of properties to remove
334 * @return self, for chaining
335 */
336 public PropertyPanel removeProps(String... keys) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700337 Set<String> forRemoval = Sets.newHashSet(keys);
338 List<Prop> toKeep = new ArrayList<>();
Simon Hunt10618f62017-06-15 19:30:52 -0700339 for (Prop p : properties) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700340 if (!forRemoval.contains(p.key())) {
341 toKeep.add(p);
Simon Hunt629b99e2015-07-27 17:38:33 -0700342 }
343 }
Simon Hunt3a0598f2015-08-04 19:59:04 -0700344 properties = toKeep;
Simon Hunt629b99e2015-07-27 17:38:33 -0700345 return this;
346 }
347
348 /**
349 * Removes all currently defined properties.
350 *
351 * @return self, for chaining
352 */
353 public PropertyPanel removeAllProps() {
354 properties.clear();
355 return this;
356 }
Simon Hunt0af1ec32015-07-24 12:17:55 -0700357
Simon Huntfb940112015-07-29 18:36:35 -0700358 /**
Simon Hunt3a0598f2015-08-04 19:59:04 -0700359 * Adds the given button descriptor to the panel data.
Simon Huntfb940112015-07-29 18:36:35 -0700360 *
Simon Hunt3a0598f2015-08-04 19:59:04 -0700361 * @param button button descriptor
Simon Huntfb940112015-07-29 18:36:35 -0700362 * @return self, for chaining
363 */
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700364 public PropertyPanel addButton(ButtonId button) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700365 buttons.add(button);
366 return this;
367 }
368
369 /**
370 * Removes buttons with the given descriptors from the list.
371 *
372 * @param descriptors descriptors to remove
373 * @return self, for chaining
374 */
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700375 public PropertyPanel removeButtons(ButtonId... descriptors) {
376 Set<ButtonId> forRemoval = Sets.newHashSet(descriptors);
377 List<ButtonId> toKeep = new ArrayList<>();
Simon Hunt10618f62017-06-15 19:30:52 -0700378 for (ButtonId bd : buttons) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700379 if (!forRemoval.contains(bd)) {
380 toKeep.add(bd);
381 }
382 }
383 buttons = toKeep;
384 return this;
385 }
386
387 /**
388 * Removes all currently defined buttons.
389 *
390 * @return self, for chaining
391 */
392 public PropertyPanel removeAllButtons() {
393 buttons.clear();
Simon Huntfb940112015-07-29 18:36:35 -0700394 return this;
395 }
396
Simon Hunt0af1ec32015-07-24 12:17:55 -0700397 // ====================
398
Simon Huntb745ca62015-07-28 15:37:11 -0700399
Simon Hunt629b99e2015-07-27 17:38:33 -0700400 /**
Simon Hunt879ce452017-08-10 23:32:00 -0700401 * Simple data carrier for a property, composed of a key/label/value trio.
Simon Hunt629b99e2015-07-27 17:38:33 -0700402 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700403 public static class Prop {
Simon Hunt629b99e2015-07-27 17:38:33 -0700404 private final String key;
Simon Hunt879ce452017-08-10 23:32:00 -0700405 private final String label;
Simon Hunt629b99e2015-07-27 17:38:33 -0700406 private final String value;
Simon Hunt0af1ec32015-07-24 12:17:55 -0700407
Simon Hunt629b99e2015-07-27 17:38:33 -0700408 /**
409 * Constructs a property data value.
410 *
Simon Hunt879ce452017-08-10 23:32:00 -0700411 * @param key property key (localization key)
412 * @param label property label (localization value)
Simon Hunt629b99e2015-07-27 17:38:33 -0700413 * @param value property value
414 */
Simon Hunt879ce452017-08-10 23:32:00 -0700415 public Prop(String key, String label, String value) {
Simon Hunt0af1ec32015-07-24 12:17:55 -0700416 this.key = key;
Simon Hunt879ce452017-08-10 23:32:00 -0700417 this.label = label;
Simon Hunt0af1ec32015-07-24 12:17:55 -0700418 this.value = value;
419 }
420
Simon Hunt629b99e2015-07-27 17:38:33 -0700421 /**
422 * Returns the property's key.
423 *
424 * @return the key
425 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700426 public String key() {
427 return key;
428 }
429
Simon Hunt629b99e2015-07-27 17:38:33 -0700430 /**
Simon Hunt879ce452017-08-10 23:32:00 -0700431 * Returns the property's (localized) label.
432 *
433 * @return the label
434 */
435 public String label() {
436 return label;
437 }
438
439 /**
Simon Hunt629b99e2015-07-27 17:38:33 -0700440 * Returns the property's value.
441 *
442 * @return the value
443 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700444 public String value() {
445 return value;
446 }
Simon Hunt629b99e2015-07-27 17:38:33 -0700447
Simon Hunt879ce452017-08-10 23:32:00 -0700448 /*
449 * NOTE: equals/hashCode are only expressed in terms of key and value.
450 */
451
Simon Hunt629b99e2015-07-27 17:38:33 -0700452 @Override
453 public boolean equals(Object o) {
454 if (this == o) {
455 return true;
456 }
457 if (o == null || getClass() != o.getClass()) {
458 return false;
459 }
460
461 Prop prop = (Prop) o;
462 return key.equals(prop.key) && value.equals(prop.value);
463 }
464
465 @Override
466 public int hashCode() {
467 int result = key.hashCode();
468 result = 31 * result + value.hashCode();
469 return result;
470 }
471
472 @Override
473 public String toString() {
Simon Hunt879ce452017-08-10 23:32:00 -0700474 return "{" + key + "(" + label + ") -> " + value + "}";
Simon Hunt629b99e2015-07-27 17:38:33 -0700475 }
Simon Hunt0af1ec32015-07-24 12:17:55 -0700476 }
477
Simon Hunt629b99e2015-07-27 17:38:33 -0700478 /**
479 * Auxiliary class representing a separator property.
480 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700481 public static class Separator extends Prop {
482 public Separator() {
Simon Hunt879ce452017-08-10 23:32:00 -0700483 super("-", "-", "");
Simon Hunt0af1ec32015-07-24 12:17:55 -0700484 }
485 }
486
Simon Hunt0af1ec32015-07-24 12:17:55 -0700487}