blob: 892a75d1de1db365d00315c5eb2289976f5acb3b [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;
Simon Hunta58d8942017-08-11 12:51:14 -070034 private String glyphId;
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
Simon Hunta58d8942017-08-11 12:51:14 -070042 * glyph identifier (icon to display).
Simon Hunt629b99e2015-07-27 17:38:33 -070043 *
Simon Hunta58d8942017-08-11 12:51:14 -070044 * @param title title text
45 * @param glyphId glyph ID
Simon Hunt629b99e2015-07-27 17:38:33 -070046 */
Simon Hunta58d8942017-08-11 12:51:14 -070047 public PropertyPanel(String title, String glyphId) {
Simon Hunt0af1ec32015-07-24 12:17:55 -070048 this.title = title;
Simon Hunta58d8942017-08-11 12:51:14 -070049 this.glyphId = glyphId;
Simon Hunt0af1ec32015-07-24 12:17:55 -070050 }
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 Hunta58d8942017-08-11 12:51:14 -0700157 * @param label property label (localized)
Simon Hunt879ce452017-08-10 23:32:00 -0700158 * @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
Simon Hunta58d8942017-08-11 12:51:14 -0700180 * @deprecated as of Loon (1.11) in deference to the localized version
Simon Hunt879ce452017-08-10 23:32:00 -0700181 */
Simon Hunta58d8942017-08-11 12:51:14 -0700182 @Deprecated
Simon Hunt879ce452017-08-10 23:32:00 -0700183 public PropertyPanel addProp(String key, String value) {
184 return addProp(key, key, value);
185 }
186
187 /**
188 * Adds a property to the panel data, using a decimal formatter.
189 * Note that the key is used as the label.
190 *
191 * @param key property key (also used as display label)
192 * @param value property value
193 * @return self, for chaining
Simon Hunta58d8942017-08-11 12:51:14 -0700194 * @deprecated as of Loon (1.11) in deference to the localized version
Simon Hunt879ce452017-08-10 23:32:00 -0700195 */
Simon Hunta58d8942017-08-11 12:51:14 -0700196 @Deprecated
Simon Hunt879ce452017-08-10 23:32:00 -0700197 public PropertyPanel addProp(String key, int value) {
198 return addProp(key, key, value);
199 }
200
201 /**
202 * Adds a property to the panel data, using a decimal formatter.
203 * Note that the key is used as the label.
204 *
205 * @param key property key (also used as display label)
206 * @param value property value
207 * @return self, for chaining
Simon Hunta58d8942017-08-11 12:51:14 -0700208 * @deprecated as of Loon (1.11) in deference to the localized version
Simon Hunt879ce452017-08-10 23:32:00 -0700209 */
Simon Hunta58d8942017-08-11 12:51:14 -0700210 @Deprecated
Simon Hunt879ce452017-08-10 23:32:00 -0700211 public PropertyPanel addProp(String key, long value) {
212 return addProp(key, key, value);
213 }
214
215 /**
216 * Adds a property to the panel data. Note that the value's
217 * {@link Object#toString toString()} method is used to convert the
218 * value to a string.
219 * Note also that the key is used as the label.
220 *
221 * @param key property key (also used as display label)
222 * @param value property value
223 * @return self, for chaining
Simon Hunta58d8942017-08-11 12:51:14 -0700224 * @deprecated as of Loon (1.11) in deference to the localized version
Simon Hunt879ce452017-08-10 23:32:00 -0700225 */
Simon Hunta58d8942017-08-11 12:51:14 -0700226 @Deprecated
Simon Hunt879ce452017-08-10 23:32:00 -0700227 public PropertyPanel addProp(String key, Object value) {
228 return addProp(key, key, value);
229 }
230
231 /**
232 * Adds a property to the panel data. Note that the value's
233 * {@link Object#toString toString()} method is used to convert the
234 * value to a string, from which the characters defined in the given
235 * regular expression string are stripped.
236 * Note also that the key is used as the label.
237 *
238 * @param key property key (also used as display label)
Simon Hunt10618f62017-06-15 19:30:52 -0700239 * @param value property value
Simon Hunt00a27ff2015-07-28 18:53:40 -0700240 * @param reStrip regexp characters to strip from value string
241 * @return self, for chaining
Simon Hunta58d8942017-08-11 12:51:14 -0700242 * @deprecated as of Loon (1.11) in deference to the localized version
Simon Hunt00a27ff2015-07-28 18:53:40 -0700243 */
Simon Hunta58d8942017-08-11 12:51:14 -0700244 @Deprecated
Simon Hunt00a27ff2015-07-28 18:53:40 -0700245 public PropertyPanel addProp(String key, Object value, String reStrip) {
Simon Hunt879ce452017-08-10 23:32:00 -0700246 return addProp(key, key, value, reStrip);
Simon Hunt00a27ff2015-07-28 18:53:40 -0700247 }
248
249 /**
250 * Adds a separator to the panel data.
251 *
252 * @return self, for chaining
253 */
254 public PropertyPanel addSeparator() {
255 properties.add(new Separator());
256 return this;
257 }
Simon Huntb745ca62015-07-28 15:37:11 -0700258
259 /**
Simon Hunt629b99e2015-07-27 17:38:33 -0700260 * Returns the title text.
261 *
262 * @return title text
263 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700264 public String title() {
265 return title;
266 }
267
Simon Hunt629b99e2015-07-27 17:38:33 -0700268 /**
Simon Hunta58d8942017-08-11 12:51:14 -0700269 * Returns the glyph identifier.
Simon Hunt629b99e2015-07-27 17:38:33 -0700270 *
Simon Hunta58d8942017-08-11 12:51:14 -0700271 * @return glyph identifier
Simon Hunt629b99e2015-07-27 17:38:33 -0700272 */
Simon Hunta58d8942017-08-11 12:51:14 -0700273 public String glyphId() {
274 return glyphId;
Simon Hunt0af1ec32015-07-24 12:17:55 -0700275 }
276
Simon Hunt629b99e2015-07-27 17:38:33 -0700277 /**
Simon Hunt10618f62017-06-15 19:30:52 -0700278 * Returns the navigation path.
279 *
280 * @return the navigation path
281 */
282 public String navPath() {
283 return navPath;
284 }
285
286 /**
Simon Huntb745ca62015-07-28 15:37:11 -0700287 * Returns the internal ID.
288 *
289 * @return the ID
290 */
291 public String id() {
292 return id;
293 }
294
295 /**
Simon Hunt629b99e2015-07-27 17:38:33 -0700296 * Returns the list of properties to be displayed.
297 *
298 * @return the property list
299 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700300 public List<Prop> properties() {
301 return properties;
302 }
303
Simon Huntfb940112015-07-29 18:36:35 -0700304 /**
305 * Returns the list of button descriptors.
306 *
307 * @return the button list
308 */
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700309 public List<ButtonId> buttons() {
Simon Huntfb940112015-07-29 18:36:35 -0700310 return buttons;
311 }
312
Simon Hunt629b99e2015-07-27 17:38:33 -0700313 // == MUTATORS
314
315 /**
316 * Sets the title text.
317 *
318 * @param title title text
319 * @return self, for chaining
320 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700321 public PropertyPanel title(String title) {
322 this.title = title;
323 return this;
324 }
325
Simon Hunt629b99e2015-07-27 17:38:33 -0700326 /**
Simon Hunta58d8942017-08-11 12:51:14 -0700327 * Sets the glyph identifier.
Simon Hunt629b99e2015-07-27 17:38:33 -0700328 *
Simon Hunta58d8942017-08-11 12:51:14 -0700329 * @param glyphId glyph identifier
Simon Hunt629b99e2015-07-27 17:38:33 -0700330 * @return self, for chaining
331 */
Simon Hunta58d8942017-08-11 12:51:14 -0700332 public PropertyPanel glyphId(String glyphId) {
333 this.glyphId = glyphId;
Simon Hunt629b99e2015-07-27 17:38:33 -0700334 return this;
335 }
Simon Hunt0af1ec32015-07-24 12:17:55 -0700336
Simon Hunt629b99e2015-07-27 17:38:33 -0700337 /**
338 * Removes properties with the given keys from the list.
339 *
340 * @param keys keys of properties to remove
341 * @return self, for chaining
342 */
343 public PropertyPanel removeProps(String... keys) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700344 Set<String> forRemoval = Sets.newHashSet(keys);
345 List<Prop> toKeep = new ArrayList<>();
Simon Hunt10618f62017-06-15 19:30:52 -0700346 for (Prop p : properties) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700347 if (!forRemoval.contains(p.key())) {
348 toKeep.add(p);
Simon Hunt629b99e2015-07-27 17:38:33 -0700349 }
350 }
Simon Hunt3a0598f2015-08-04 19:59:04 -0700351 properties = toKeep;
Simon Hunt629b99e2015-07-27 17:38:33 -0700352 return this;
353 }
354
355 /**
356 * Removes all currently defined properties.
357 *
358 * @return self, for chaining
359 */
360 public PropertyPanel removeAllProps() {
361 properties.clear();
362 return this;
363 }
Simon Hunt0af1ec32015-07-24 12:17:55 -0700364
Simon Huntfb940112015-07-29 18:36:35 -0700365 /**
Simon Hunt3a0598f2015-08-04 19:59:04 -0700366 * Adds the given button descriptor to the panel data.
Simon Huntfb940112015-07-29 18:36:35 -0700367 *
Simon Hunt3a0598f2015-08-04 19:59:04 -0700368 * @param button button descriptor
Simon Huntfb940112015-07-29 18:36:35 -0700369 * @return self, for chaining
370 */
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700371 public PropertyPanel addButton(ButtonId button) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700372 buttons.add(button);
373 return this;
374 }
375
376 /**
377 * Removes buttons with the given descriptors from the list.
378 *
379 * @param descriptors descriptors to remove
380 * @return self, for chaining
381 */
Simon Hunt8d22c4b2015-08-06 16:24:43 -0700382 public PropertyPanel removeButtons(ButtonId... descriptors) {
383 Set<ButtonId> forRemoval = Sets.newHashSet(descriptors);
384 List<ButtonId> toKeep = new ArrayList<>();
Simon Hunt10618f62017-06-15 19:30:52 -0700385 for (ButtonId bd : buttons) {
Simon Hunt3a0598f2015-08-04 19:59:04 -0700386 if (!forRemoval.contains(bd)) {
387 toKeep.add(bd);
388 }
389 }
390 buttons = toKeep;
391 return this;
392 }
393
394 /**
395 * Removes all currently defined buttons.
396 *
397 * @return self, for chaining
398 */
399 public PropertyPanel removeAllButtons() {
400 buttons.clear();
Simon Huntfb940112015-07-29 18:36:35 -0700401 return this;
402 }
403
Simon Hunt0af1ec32015-07-24 12:17:55 -0700404 // ====================
405
Simon Huntb745ca62015-07-28 15:37:11 -0700406
Simon Hunt629b99e2015-07-27 17:38:33 -0700407 /**
Simon Hunt879ce452017-08-10 23:32:00 -0700408 * Simple data carrier for a property, composed of a key/label/value trio.
Simon Hunt629b99e2015-07-27 17:38:33 -0700409 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700410 public static class Prop {
Simon Hunt629b99e2015-07-27 17:38:33 -0700411 private final String key;
Simon Hunt879ce452017-08-10 23:32:00 -0700412 private final String label;
Simon Hunt629b99e2015-07-27 17:38:33 -0700413 private final String value;
Simon Hunt0af1ec32015-07-24 12:17:55 -0700414
Simon Hunt629b99e2015-07-27 17:38:33 -0700415 /**
416 * Constructs a property data value.
417 *
Simon Hunt879ce452017-08-10 23:32:00 -0700418 * @param key property key (localization key)
419 * @param label property label (localization value)
Simon Hunt629b99e2015-07-27 17:38:33 -0700420 * @param value property value
421 */
Simon Hunt879ce452017-08-10 23:32:00 -0700422 public Prop(String key, String label, String value) {
Simon Hunt0af1ec32015-07-24 12:17:55 -0700423 this.key = key;
Simon Hunt879ce452017-08-10 23:32:00 -0700424 this.label = label;
Simon Hunt0af1ec32015-07-24 12:17:55 -0700425 this.value = value;
426 }
427
Simon Hunt629b99e2015-07-27 17:38:33 -0700428 /**
429 * Returns the property's key.
430 *
431 * @return the key
432 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700433 public String key() {
434 return key;
435 }
436
Simon Hunt629b99e2015-07-27 17:38:33 -0700437 /**
Simon Hunt879ce452017-08-10 23:32:00 -0700438 * Returns the property's (localized) label.
439 *
440 * @return the label
441 */
442 public String label() {
443 return label;
444 }
445
446 /**
Simon Hunt629b99e2015-07-27 17:38:33 -0700447 * Returns the property's value.
448 *
449 * @return the value
450 */
Simon Hunt0af1ec32015-07-24 12:17:55 -0700451 public String value() {
452 return value;
453 }
Simon Hunt629b99e2015-07-27 17:38:33 -0700454
Simon Hunt879ce452017-08-10 23:32:00 -0700455 /*
456 * NOTE: equals/hashCode are only expressed in terms of key and value.
457 */
458
Simon Hunt629b99e2015-07-27 17:38:33 -0700459 @Override
460 public boolean equals(Object o) {
461 if (this == o) {
462 return true;
463 }
464 if (o == null || getClass() != o.getClass()) {
465 return false;
466 }
467
468 Prop prop = (Prop) o;
469 return key.equals(prop.key) && value.equals(prop.value);
470 }
471
472 @Override
473 public int hashCode() {
474 int result = key.hashCode();
475 result = 31 * result + value.hashCode();
476 return result;
477 }
478
479 @Override
480 public String toString() {
Simon Hunt879ce452017-08-10 23:32:00 -0700481 return "{" + key + "(" + label + ") -> " + value + "}";
Simon Hunt629b99e2015-07-27 17:38:33 -0700482 }
Simon Hunt0af1ec32015-07-24 12:17:55 -0700483 }
484
Simon Hunt629b99e2015-07-27 17:38:33 -0700485 /**
486 * Auxiliary class representing a separator property.
487 */
Simon Hunta58d8942017-08-11 12:51:14 -0700488 static class Separator extends Prop {
489 Separator() {
Simon Hunt879ce452017-08-10 23:32:00 -0700490 super("-", "-", "");
Simon Hunt0af1ec32015-07-24 12:17:55 -0700491 }
492 }
493
Simon Hunt0af1ec32015-07-24 12:17:55 -0700494}