blob: b37f1dfd1f261f11506f59f73e7572be616123db [file] [log] [blame]
Simon Huntf679c4e2016-04-01 17:02:24 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Simon Huntf679c4e2016-04-01 17:02:24 -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
17package org.onosproject.ui.model.topo;
18
Simon Huntd0fa2842016-10-24 18:04:05 -070019import com.google.common.base.MoreObjects;
Simon Huntf679c4e2016-04-01 17:02:24 -070020import org.onosproject.net.region.Region;
Simon Huntd5b96732016-07-08 13:22:27 -070021import org.onosproject.net.region.RegionId;
Simon Huntf679c4e2016-04-01 17:02:24 -070022
Simon Huntd0fa2842016-10-24 18:04:05 -070023import static com.google.common.base.Preconditions.checkArgument;
24import static com.google.common.base.Preconditions.checkNotNull;
25
Simon Huntf679c4e2016-04-01 17:02:24 -070026/**
27 * Represents a specific "subset" of the UI model of the network topology
28 * that a user might wish to view. Backed by a {@link Region}.
Simon Huntd0fa2842016-10-24 18:04:05 -070029 * <p>
30 * These instances include information about which geo-map (or sprite definition)
31 * should be displayed, along with zoom and offset parameters.
Simon Huntf679c4e2016-04-01 17:02:24 -070032 */
33public class UiTopoLayout {
34
Simon Huntd0fa2842016-10-24 18:04:05 -070035 // package private for unit test access
36 static final double SCALE_MIN = 0.01;
37 static final double SCALE_MAX = 100.0;
38 static final double SCALE_DEFAULT = 1.0;
39 static final double OFFSET_DEFAULT = 0.0;
40
41 static final String E_ROOT_PARENT = "Cannot change parent ID of root layout";
42 static final String E_ROOT_REGION = "Cannot set region on root layout";
43 static final String E_SPRITES_SET = "Cannot set geomap if sprites is set";
44 static final String E_GEOMAP_SET = "Cannot set sprites if geomap is set";
45 static final String E_SCALE_OOB =
46 "Scale out of bounds; expected [" + SCALE_MIN + ".." + SCALE_MAX + "]";
47
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -070048 private final UiTopoLayoutId id;
Simon Huntd0fa2842016-10-24 18:04:05 -070049
50 private Region region;
51 private UiTopoLayoutId parent;
52 private String geomap;
53 private String sprites;
54 private double scale = SCALE_DEFAULT;
55 private double offsetX = OFFSET_DEFAULT;
56 private double offsetY = OFFSET_DEFAULT;
Simon Huntf679c4e2016-04-01 17:02:24 -070057
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -070058 /**
59 * Created a new UI topology layout.
60 *
Simon Huntd0fa2842016-10-24 18:04:05 -070061 * @param id layout identifier
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -070062 */
Simon Huntd0fa2842016-10-24 18:04:05 -070063 public UiTopoLayout(UiTopoLayoutId id) {
64 checkNotNull(id, "layout ID cannot be null");
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -070065 this.id = id;
Simon Huntd0fa2842016-10-24 18:04:05 -070066
Simon Hunt98189192016-07-29 19:02:27 -070067 // NOTE: root layout is its own parent...
Simon Huntd0fa2842016-10-24 18:04:05 -070068 if (isRoot()) {
69 parent = id;
70 }
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -070071 }
72
Simon Huntd0fa2842016-10-24 18:04:05 -070073 /**
74 * Returns true if this layout instance is at the top of the
75 * hierarchy tree.
76 *
77 * @return true if this is the root layout
78 */
79 public boolean isRoot() {
80 return UiTopoLayoutId.DEFAULT_ID.equals(id);
Simon Huntd5b96732016-07-08 13:22:27 -070081 }
82
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -070083 /**
84 * Returns the UI layout identifier.
85 *
86 * @return identifier of the layout
87 */
88 public UiTopoLayoutId id() {
89 return id;
90 }
91
Simon Huntd0fa2842016-10-24 18:04:05 -070092 @Override
93 public String toString() {
94 return MoreObjects.toStringHelper(this)
95 .add("id", id)
96 .add("region", region)
97 .add("parent", parent)
98 .add("geomap", geomap)
99 .add("sprites", sprites)
100 .add("scale", scale)
101 .add("offsetX", offsetX)
102 .add("offsetY", offsetY)
103 .toString();
104 }
105
106 /**
107 * Sets the backing region for this layout. Note that an exception will
108 * be thrown if this is the root layout.
109 *
110 * @param region the backing region
111 * @return self, for chaining
112 * @throws IllegalArgumentException if this is the root layout
113 */
114 public UiTopoLayout region(Region region) {
115 if (isRoot()) {
116 throw new IllegalArgumentException(E_ROOT_REGION);
117 }
118
119 this.region = region;
120 return this;
121 }
122
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -0700123 /**
Simon Huntd5b96732016-07-08 13:22:27 -0700124 * Returns the backing region with which this layout is associated. Note
125 * that this may be null (for the root layout).
Thomas Vachuska4d66d0a2016-04-15 15:48:13 -0700126 *
127 * @return backing region
128 */
129 public Region region() {
130 return region;
131 }
132
Thomas Vachuska92b016b2016-05-20 11:37:57 -0700133 /**
Simon Hunt4f4ffc32016-08-03 18:30:47 -0700134 * Returns the identifier of the backing region. If this is the default
135 * layout, the null-region ID will be returned, otherwise the ID of the
136 * backing region for this layout will be returned; null in the case that
137 * there is no backing region.
Simon Huntd5b96732016-07-08 13:22:27 -0700138 *
139 * @return backing region identifier
140 */
141 public RegionId regionId() {
Simon Huntd0fa2842016-10-24 18:04:05 -0700142 return isRoot() ? UiRegion.NULL_ID :
143 (region == null ? null : region.id());
144 }
145
146 /**
147 * Sets the identity of this layout's parent. May be null to unset.
148 * Note that an exception will be thrown if this is the root layout,
149 * since the parent of the root is always itself, and cannot be changed.
150 *
151 * @param parentId parent layout identifier
152 * @return self, for chaining
153 * @throws IllegalArgumentException if this instance is the root layout
154 */
155 public UiTopoLayout parent(UiTopoLayoutId parentId) {
156 if (isRoot()) {
157 throw new IllegalArgumentException(E_ROOT_PARENT);
158 }
159 // TODO: consider checking ancestry chain to prevent loops
160
161 parent = parentId;
162 return this;
Simon Huntd5b96732016-07-08 13:22:27 -0700163 }
164
165 /**
Thomas Vachuska92b016b2016-05-20 11:37:57 -0700166 * Returns the parent layout identifier.
167 *
168 * @return parent layout identifier
169 */
170 public UiTopoLayoutId parent() {
171 return parent;
172 }
173
Simon Hunt98189192016-07-29 19:02:27 -0700174 /**
Simon Huntd0fa2842016-10-24 18:04:05 -0700175 * Sets the name of the geomap for this layout. This is the symbolic
176 * name for a "topojson" file containing a geographic map projection,
177 * to be displayed in the topology view, for this layout.
178 * <p>
179 * Since the geomap and sprites fields are mutually exclusive, this
180 * method will throw an exception if the sprites field is already set.
Simon Hunt98189192016-07-29 19:02:27 -0700181 *
Simon Huntd0fa2842016-10-24 18:04:05 -0700182 * @param geomap the geomap name
183 * @return self, for chaining
184 * @throws IllegalArgumentException if the sprites field is not null
Simon Hunt98189192016-07-29 19:02:27 -0700185 */
Simon Huntd0fa2842016-10-24 18:04:05 -0700186 public UiTopoLayout geomap(String geomap) {
187 if (sprites != null) {
188 throw new IllegalArgumentException(E_SPRITES_SET);
189 }
190 this.geomap = geomap;
191 return this;
Simon Hunt98189192016-07-29 19:02:27 -0700192 }
Simon Huntd0fa2842016-10-24 18:04:05 -0700193
194 /**
195 * Returns the symbolic name for the geomap for this layout.
196 *
197 * @return name of geomap
198 */
199 public String geomap() {
200 return geomap;
201 }
202
203 /**
204 * Sets the name of the sprites definition for this layout. This is the
205 * symbolic name for a "json" file containing a definition of sprites,
206 * which render as a symbolic background (e.g. a campus, or floor plan),
207 * to be displayed in the topology view, for this layout.
208 * <p>
209 * Since the geomap and sprites fields are mutually exclusive, this
210 * method will throw an exception if the geomap field is already set.
211 *
212 * @param sprites the sprites definition name
213 * @return self, for chaining
214 * @throws IllegalArgumentException if the geomap field is not null
215 */
216 public UiTopoLayout sprites(String sprites) {
217 if (geomap != null) {
218 throw new IllegalArgumentException(E_GEOMAP_SET);
219 }
220 this.sprites = sprites;
221 return this;
222 }
223
224 /**
225 * Returns the symbolic name for the sprites definition for this layout.
226 *
227 * @return name of sprites definition
228 */
229 public String sprites() {
230 return sprites;
231 }
232
233 private boolean scaleWithinBounds(double scale) {
234 return scale >= SCALE_MIN && scale <= SCALE_MAX;
235 }
236
237 /**
238 * Sets the scale for the geomap / sprite image. Note that the
239 * acceptable bounds are from {@value #SCALE_MIN} to {@value #SCALE_MAX}.
240 *
241 * @param scale the scale
242 * @return self for chaining
243 * @throws IllegalArgumentException if the value is out of bounds
244 */
245 public UiTopoLayout scale(double scale) {
246 checkArgument(scaleWithinBounds(scale), E_SCALE_OOB);
247 this.scale = scale;
248 return this;
249 }
250
251 /**
252 * Returns the scale for the geomap / sprite image.
253 *
254 * @return the scale
255 */
256 public double scale() {
257 return scale;
258 }
259
260 /**
261 * Sets the x-offset value.
262 *
263 * @param offsetX x-offset
264 * @return self, for chaining
265 */
266 public UiTopoLayout offsetX(double offsetX) {
267 this.offsetX = offsetX;
268 return this;
269 }
270
271 /**
272 * Returns the x-offset value.
273 *
274 * @return the x-offset
275 */
276 public double offsetX() {
277 return offsetX;
278 }
279
280 /**
281 * Sets the y-offset value.
282 *
283 * @param offsetY y-offset
284 * @return self, for chaining
285 */
286 public UiTopoLayout offsetY(double offsetY) {
287 this.offsetY = offsetY;
288 return this;
289 }
290
291 /**
292 * Returns the y-offset value.
293 *
294 * @return the y-offset
295 */
296 public double offsetY() {
297 return offsetY;
298 }
299
Simon Huntf679c4e2016-04-01 17:02:24 -0700300}