blob: 8e83f20b980a06704b4bacdc72d917f1cbacbc43 [file] [log] [blame]
Simon Huntc4ca7102017-04-08 22:28:04 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Simon Huntc4ca7102017-04-08 22:28:04 -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.
15 *
16 */
17
18package org.onosproject.ui.topo;
19
Simon Hunt8f60ff82017-04-24 17:19:30 -070020import com.google.common.base.Strings;
21
22import java.util.ArrayList;
23import java.util.Arrays;
24import java.util.List;
25
Simon Huntc4ca7102017-04-08 22:28:04 -070026import static com.google.common.base.MoreObjects.toStringHelper;
27import static com.google.common.base.Preconditions.checkNotNull;
28
29/**
30 * Represents a "node location" on a UI layout.
31 */
32public final class LayoutLocation {
33 private static final double ZERO_THRESHOLD = Double.MIN_VALUE * 2.0;
Simon Hunt8f60ff82017-04-24 17:19:30 -070034 private static final String COMMA = ",";
35 private static final String TILDE = "~";
36 private static final String EMPTY = "";
37
38 private static final String E_BAD_COMPACT = "Badly formatted compact form: ";
39 private static final String E_EMPTY_ID = "id must be non-empty";
40 private static final String E_BAD_DOUBLE = "unparsable double";
41
Simon Huntc4ca7102017-04-08 22:28:04 -070042
43 /**
44 * Designates the type of location; either geographic or logical grid.
45 */
46 public enum Type {
Simon Huntf27a9292017-05-04 17:36:26 -070047 GEO, GRID;
48
49 @Override
50 public String toString() {
51 return name().toLowerCase();
52 }
Simon Huntc4ca7102017-04-08 22:28:04 -070053 }
54
55 private final String id;
56 private final double latOrY;
57 private final double longOrX;
58 private final Type locType;
59
60 private LayoutLocation(String id, Type locType, double latOrY, double longOrX) {
61 this.id = id;
62 this.latOrY = latOrY;
63 this.longOrX = longOrX;
64 this.locType = locType;
65 }
66
Simon Huntc4ca7102017-04-08 22:28:04 -070067 private boolean doubleIsZero(double value) {
68 return value >= -ZERO_THRESHOLD && value <= ZERO_THRESHOLD;
69 }
70
71 /**
72 * Returns true if the coordinates indicate the origin (0, 0) of the
73 * coordinate system; false otherwise.
74 *
75 * @return true if geo-coordinates are set; false otherwise
76 */
77 public boolean isOrigin() {
78 return doubleIsZero(latOrY) && doubleIsZero(longOrX);
79 }
80
81 /**
82 * Returns the identifier associated with this location.
83 *
84 * @return the identifier
85 */
86 public String id() {
87 return id;
88 }
89
90 /**
Simon Hunt8f60ff82017-04-24 17:19:30 -070091 * Returns the location type (geo or grid), which indicates how the data
92 * is to be interpreted.
93 *
94 * @return location type
95 */
96 public Type locType() {
97 return locType;
98 }
99
100 /**
Simon Huntc4ca7102017-04-08 22:28:04 -0700101 * Returns the latitude (geo) or y-coord (grid) data value.
102 *
103 * @return geo latitude or grid y-coord
104 */
105 public double latOrY() {
106 return latOrY;
107 }
108
109 /**
110 * Returns the longitude (geo) or x-coord (grid) data value.
111 *
112 * @return geo longitude or grid x-coord
113 */
114 public double longOrX() {
115 return longOrX;
116 }
117
Simon Huntc4ca7102017-04-08 22:28:04 -0700118 @Override
119 public String toString() {
120 return toStringHelper(this)
121 .add("id", id)
Simon Hunt8f60ff82017-04-24 17:19:30 -0700122 .add("loc-type", locType)
Simon Huntc4ca7102017-04-08 22:28:04 -0700123 .add("lat/Y", latOrY)
124 .add("long/X", longOrX)
Simon Huntc4ca7102017-04-08 22:28:04 -0700125 .toString();
126 }
127
128 /**
Simon Hunt8f60ff82017-04-24 17:19:30 -0700129 * Produces a compact string representation of this instance.
130 *
131 * @return compact string rep
132 */
133 public String toCompactListString() {
134 return id + COMMA + locType + COMMA + latOrY + COMMA + longOrX;
135 }
136
137 /**
138 * Produces a layout location instance from a compact string representation.
139 *
140 * @param s the compact string
141 * @return a corresponding instance
142 */
143 public static LayoutLocation fromCompactString(String s) {
144 String[] tokens = s.split(COMMA);
145 if (tokens.length != 4) {
146 throw new IllegalArgumentException(E_BAD_COMPACT + s);
147 }
148 String id = tokens[0];
149 String type = tokens[1];
150 String latY = tokens[2];
151 String longX = tokens[3];
152
153 if (Strings.isNullOrEmpty(id)) {
154 throw new IllegalArgumentException(E_BAD_COMPACT + E_EMPTY_ID);
155 }
156
157 double latOrY;
158 double longOrX;
159 try {
160 latOrY = Double.parseDouble(latY);
161 longOrX = Double.parseDouble(longX);
162 } catch (NumberFormatException nfe) {
163 throw new IllegalArgumentException(E_BAD_COMPACT + E_BAD_DOUBLE);
164 }
165
166 return LayoutLocation.layoutLocation(id, type, latOrY, longOrX);
167 }
168
169 /**
170 * Produces a compact encoding of a list of layout locations.
171 *
172 * @param locs array of layout location instances
173 * @return string encoding
174 */
175 public static String toCompactListString(LayoutLocation... locs) {
176 if (locs == null || locs.length == 0) {
177 return EMPTY;
178 }
179 List<LayoutLocation> lls = Arrays.asList(locs);
180 return toCompactListString(lls);
181 }
182
183 /**
184 * Produces a compact encoding of a list of layout locations.
185 *
186 * @param locs list of layout location instances
187 * @return string encoding
188 */
189 public static String toCompactListString(List<LayoutLocation> locs) {
190 // note: locs may be empty
191 if (locs == null || locs.isEmpty()) {
192 return EMPTY;
193 }
194
195 StringBuilder sb = new StringBuilder();
196 for (LayoutLocation ll : locs) {
197 sb.append(ll.toCompactListString()).append(TILDE);
198 }
199 final int len = sb.length();
200 sb.replace(len - 1, len, "");
201 return sb.toString();
202 }
203
204 /**
205 * Returns a list of layout locations from a compact string representation.
206 *
207 * @param compactList string representation
208 * @return corresponding list of layout locations
209 */
210 public static List<LayoutLocation> fromCompactListString(String compactList) {
211 List<LayoutLocation> locs = new ArrayList<>();
212 if (!Strings.isNullOrEmpty(compactList)) {
213 String[] items = compactList.split(TILDE);
214 for (String s : items) {
215 locs.add(fromCompactString(s));
216 }
217 }
218 return locs;
219 }
220
221
222 /**
Simon Huntc4ca7102017-04-08 22:28:04 -0700223 * Creates an instance of a layout location.
224 *
225 * @param id an identifier for the item at this location
226 * @param locType the location type
227 * @param latOrY geo latitude / grid y-coord
228 * @param longOrX geo longitude / grid x-coord
229 * @return layout location instance
230 */
231 public static LayoutLocation layoutLocation(String id, Type locType,
232 double latOrY, double longOrX) {
233 checkNotNull(id, "must supply an identifier");
234 checkNotNull(locType, "must declare location type");
235 return new LayoutLocation(id, locType, latOrY, longOrX);
236 }
237
238 /**
239 * Creates an instance of a layout location.
240 *
241 * @param id an identifier for the item at this location
242 * @param locType the location type ("geo" or "grid")
243 * @param latOrY geo latitude / grid y-coord
244 * @param longOrX geo longitude / grid x-coord
245 * @return layout location instance
246 * @throws IllegalArgumentException if the type is not "geo" or "grid"
247 */
248 public static LayoutLocation layoutLocation(String id, String locType,
249 double latOrY, double longOrX) {
250 Type t = Type.valueOf(locType.toUpperCase());
251 return new LayoutLocation(id, t, latOrY, longOrX);
252 }
253}