blob: 69be6aa07ddc1dd3d4b9f10f3864ac727256f5ff [file] [log] [blame]
Simon Huntc4ca7102017-04-08 22:28:04 -07001/*
2 * Copyright 2017-present 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 *
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 {
47 GEO, GRID
48 }
49
50 private final String id;
51 private final double latOrY;
52 private final double longOrX;
53 private final Type locType;
54
55 private LayoutLocation(String id, Type locType, double latOrY, double longOrX) {
56 this.id = id;
57 this.latOrY = latOrY;
58 this.longOrX = longOrX;
59 this.locType = locType;
60 }
61
Simon Huntc4ca7102017-04-08 22:28:04 -070062 private boolean doubleIsZero(double value) {
63 return value >= -ZERO_THRESHOLD && value <= ZERO_THRESHOLD;
64 }
65
66 /**
67 * Returns true if the coordinates indicate the origin (0, 0) of the
68 * coordinate system; false otherwise.
69 *
70 * @return true if geo-coordinates are set; false otherwise
71 */
72 public boolean isOrigin() {
73 return doubleIsZero(latOrY) && doubleIsZero(longOrX);
74 }
75
76 /**
77 * Returns the identifier associated with this location.
78 *
79 * @return the identifier
80 */
81 public String id() {
82 return id;
83 }
84
85 /**
Simon Hunt8f60ff82017-04-24 17:19:30 -070086 * Returns the location type (geo or grid), which indicates how the data
87 * is to be interpreted.
88 *
89 * @return location type
90 */
91 public Type locType() {
92 return locType;
93 }
94
95 /**
Simon Huntc4ca7102017-04-08 22:28:04 -070096 * Returns the latitude (geo) or y-coord (grid) data value.
97 *
98 * @return geo latitude or grid y-coord
99 */
100 public double latOrY() {
101 return latOrY;
102 }
103
104 /**
105 * Returns the longitude (geo) or x-coord (grid) data value.
106 *
107 * @return geo longitude or grid x-coord
108 */
109 public double longOrX() {
110 return longOrX;
111 }
112
Simon Huntc4ca7102017-04-08 22:28:04 -0700113 @Override
114 public String toString() {
115 return toStringHelper(this)
116 .add("id", id)
Simon Hunt8f60ff82017-04-24 17:19:30 -0700117 .add("loc-type", locType)
Simon Huntc4ca7102017-04-08 22:28:04 -0700118 .add("lat/Y", latOrY)
119 .add("long/X", longOrX)
Simon Huntc4ca7102017-04-08 22:28:04 -0700120 .toString();
121 }
122
123 /**
Simon Hunt8f60ff82017-04-24 17:19:30 -0700124 * Produces a compact string representation of this instance.
125 *
126 * @return compact string rep
127 */
128 public String toCompactListString() {
129 return id + COMMA + locType + COMMA + latOrY + COMMA + longOrX;
130 }
131
132 /**
133 * Produces a layout location instance from a compact string representation.
134 *
135 * @param s the compact string
136 * @return a corresponding instance
137 */
138 public static LayoutLocation fromCompactString(String s) {
139 String[] tokens = s.split(COMMA);
140 if (tokens.length != 4) {
141 throw new IllegalArgumentException(E_BAD_COMPACT + s);
142 }
143 String id = tokens[0];
144 String type = tokens[1];
145 String latY = tokens[2];
146 String longX = tokens[3];
147
148 if (Strings.isNullOrEmpty(id)) {
149 throw new IllegalArgumentException(E_BAD_COMPACT + E_EMPTY_ID);
150 }
151
152 double latOrY;
153 double longOrX;
154 try {
155 latOrY = Double.parseDouble(latY);
156 longOrX = Double.parseDouble(longX);
157 } catch (NumberFormatException nfe) {
158 throw new IllegalArgumentException(E_BAD_COMPACT + E_BAD_DOUBLE);
159 }
160
161 return LayoutLocation.layoutLocation(id, type, latOrY, longOrX);
162 }
163
164 /**
165 * Produces a compact encoding of a list of layout locations.
166 *
167 * @param locs array of layout location instances
168 * @return string encoding
169 */
170 public static String toCompactListString(LayoutLocation... locs) {
171 if (locs == null || locs.length == 0) {
172 return EMPTY;
173 }
174 List<LayoutLocation> lls = Arrays.asList(locs);
175 return toCompactListString(lls);
176 }
177
178 /**
179 * Produces a compact encoding of a list of layout locations.
180 *
181 * @param locs list of layout location instances
182 * @return string encoding
183 */
184 public static String toCompactListString(List<LayoutLocation> locs) {
185 // note: locs may be empty
186 if (locs == null || locs.isEmpty()) {
187 return EMPTY;
188 }
189
190 StringBuilder sb = new StringBuilder();
191 for (LayoutLocation ll : locs) {
192 sb.append(ll.toCompactListString()).append(TILDE);
193 }
194 final int len = sb.length();
195 sb.replace(len - 1, len, "");
196 return sb.toString();
197 }
198
199 /**
200 * Returns a list of layout locations from a compact string representation.
201 *
202 * @param compactList string representation
203 * @return corresponding list of layout locations
204 */
205 public static List<LayoutLocation> fromCompactListString(String compactList) {
206 List<LayoutLocation> locs = new ArrayList<>();
207 if (!Strings.isNullOrEmpty(compactList)) {
208 String[] items = compactList.split(TILDE);
209 for (String s : items) {
210 locs.add(fromCompactString(s));
211 }
212 }
213 return locs;
214 }
215
216
217 /**
Simon Huntc4ca7102017-04-08 22:28:04 -0700218 * Creates an instance of a layout location.
219 *
220 * @param id an identifier for the item at this location
221 * @param locType the location type
222 * @param latOrY geo latitude / grid y-coord
223 * @param longOrX geo longitude / grid x-coord
224 * @return layout location instance
225 */
226 public static LayoutLocation layoutLocation(String id, Type locType,
227 double latOrY, double longOrX) {
228 checkNotNull(id, "must supply an identifier");
229 checkNotNull(locType, "must declare location type");
230 return new LayoutLocation(id, locType, latOrY, longOrX);
231 }
232
233 /**
234 * Creates an instance of a layout location.
235 *
236 * @param id an identifier for the item at this location
237 * @param locType the location type ("geo" or "grid")
238 * @param latOrY geo latitude / grid y-coord
239 * @param longOrX geo longitude / grid x-coord
240 * @return layout location instance
241 * @throws IllegalArgumentException if the type is not "geo" or "grid"
242 */
243 public static LayoutLocation layoutLocation(String id, String locType,
244 double latOrY, double longOrX) {
245 Type t = Type.valueOf(locType.toUpperCase());
246 return new LayoutLocation(id, t, latOrY, longOrX);
247 }
248}