blob: 69be6aa07ddc1dd3d4b9f10f3864ac727256f5ff [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.onosproject.ui.topo;
import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a "node location" on a UI layout.
*/
public final class LayoutLocation {
private static final double ZERO_THRESHOLD = Double.MIN_VALUE * 2.0;
private static final String COMMA = ",";
private static final String TILDE = "~";
private static final String EMPTY = "";
private static final String E_BAD_COMPACT = "Badly formatted compact form: ";
private static final String E_EMPTY_ID = "id must be non-empty";
private static final String E_BAD_DOUBLE = "unparsable double";
/**
* Designates the type of location; either geographic or logical grid.
*/
public enum Type {
GEO, GRID
}
private final String id;
private final double latOrY;
private final double longOrX;
private final Type locType;
private LayoutLocation(String id, Type locType, double latOrY, double longOrX) {
this.id = id;
this.latOrY = latOrY;
this.longOrX = longOrX;
this.locType = locType;
}
private boolean doubleIsZero(double value) {
return value >= -ZERO_THRESHOLD && value <= ZERO_THRESHOLD;
}
/**
* Returns true if the coordinates indicate the origin (0, 0) of the
* coordinate system; false otherwise.
*
* @return true if geo-coordinates are set; false otherwise
*/
public boolean isOrigin() {
return doubleIsZero(latOrY) && doubleIsZero(longOrX);
}
/**
* Returns the identifier associated with this location.
*
* @return the identifier
*/
public String id() {
return id;
}
/**
* Returns the location type (geo or grid), which indicates how the data
* is to be interpreted.
*
* @return location type
*/
public Type locType() {
return locType;
}
/**
* Returns the latitude (geo) or y-coord (grid) data value.
*
* @return geo latitude or grid y-coord
*/
public double latOrY() {
return latOrY;
}
/**
* Returns the longitude (geo) or x-coord (grid) data value.
*
* @return geo longitude or grid x-coord
*/
public double longOrX() {
return longOrX;
}
@Override
public String toString() {
return toStringHelper(this)
.add("id", id)
.add("loc-type", locType)
.add("lat/Y", latOrY)
.add("long/X", longOrX)
.toString();
}
/**
* Produces a compact string representation of this instance.
*
* @return compact string rep
*/
public String toCompactListString() {
return id + COMMA + locType + COMMA + latOrY + COMMA + longOrX;
}
/**
* Produces a layout location instance from a compact string representation.
*
* @param s the compact string
* @return a corresponding instance
*/
public static LayoutLocation fromCompactString(String s) {
String[] tokens = s.split(COMMA);
if (tokens.length != 4) {
throw new IllegalArgumentException(E_BAD_COMPACT + s);
}
String id = tokens[0];
String type = tokens[1];
String latY = tokens[2];
String longX = tokens[3];
if (Strings.isNullOrEmpty(id)) {
throw new IllegalArgumentException(E_BAD_COMPACT + E_EMPTY_ID);
}
double latOrY;
double longOrX;
try {
latOrY = Double.parseDouble(latY);
longOrX = Double.parseDouble(longX);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException(E_BAD_COMPACT + E_BAD_DOUBLE);
}
return LayoutLocation.layoutLocation(id, type, latOrY, longOrX);
}
/**
* Produces a compact encoding of a list of layout locations.
*
* @param locs array of layout location instances
* @return string encoding
*/
public static String toCompactListString(LayoutLocation... locs) {
if (locs == null || locs.length == 0) {
return EMPTY;
}
List<LayoutLocation> lls = Arrays.asList(locs);
return toCompactListString(lls);
}
/**
* Produces a compact encoding of a list of layout locations.
*
* @param locs list of layout location instances
* @return string encoding
*/
public static String toCompactListString(List<LayoutLocation> locs) {
// note: locs may be empty
if (locs == null || locs.isEmpty()) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (LayoutLocation ll : locs) {
sb.append(ll.toCompactListString()).append(TILDE);
}
final int len = sb.length();
sb.replace(len - 1, len, "");
return sb.toString();
}
/**
* Returns a list of layout locations from a compact string representation.
*
* @param compactList string representation
* @return corresponding list of layout locations
*/
public static List<LayoutLocation> fromCompactListString(String compactList) {
List<LayoutLocation> locs = new ArrayList<>();
if (!Strings.isNullOrEmpty(compactList)) {
String[] items = compactList.split(TILDE);
for (String s : items) {
locs.add(fromCompactString(s));
}
}
return locs;
}
/**
* Creates an instance of a layout location.
*
* @param id an identifier for the item at this location
* @param locType the location type
* @param latOrY geo latitude / grid y-coord
* @param longOrX geo longitude / grid x-coord
* @return layout location instance
*/
public static LayoutLocation layoutLocation(String id, Type locType,
double latOrY, double longOrX) {
checkNotNull(id, "must supply an identifier");
checkNotNull(locType, "must declare location type");
return new LayoutLocation(id, locType, latOrY, longOrX);
}
/**
* Creates an instance of a layout location.
*
* @param id an identifier for the item at this location
* @param locType the location type ("geo" or "grid")
* @param latOrY geo latitude / grid y-coord
* @param longOrX geo longitude / grid x-coord
* @return layout location instance
* @throws IllegalArgumentException if the type is not "geo" or "grid"
*/
public static LayoutLocation layoutLocation(String id, String locType,
double latOrY, double longOrX) {
Type t = Type.valueOf(locType.toUpperCase());
return new LayoutLocation(id, t, latOrY, longOrX);
}
}