Jonathan Hart | 23701d1 | 2014-04-03 10:45:48 -0700 | [diff] [blame] | 1 | package net.onrc.onos.core.util; |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 2 | |
Jonathan Hart | 46cc07f | 2014-08-21 18:59:48 -0700 | [diff] [blame] | 3 | import java.util.Objects; |
| 4 | |
Jonathan Hart | 23701d1 | 2014-04-03 10:45:48 -0700 | [diff] [blame] | 5 | import net.onrc.onos.core.util.serializers.IPv4NetDeserializer; |
| 6 | import net.onrc.onos.core.util.serializers.IPv4NetSerializer; |
Pavlin Radoslavov | ad008e0 | 2013-02-21 18:42:42 -0800 | [diff] [blame] | 7 | |
Pavlin Radoslavov | 2013cbb | 2013-02-26 10:15:18 -0800 | [diff] [blame] | 8 | import org.codehaus.jackson.map.annotate.JsonDeserialize; |
Pavlin Radoslavov | ad008e0 | 2013-02-21 18:42:42 -0800 | [diff] [blame] | 9 | import org.codehaus.jackson.map.annotate.JsonSerialize; |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 10 | |
| 11 | /** |
| 12 | * The class representing an IPv4 network address. |
Pavlin Radoslavov | 29a2a88 | 2014-04-08 17:40:54 -0700 | [diff] [blame] | 13 | * This class is immutable. |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 14 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 15 | @JsonDeserialize(using = IPv4NetDeserializer.class) |
| 16 | @JsonSerialize(using = IPv4NetSerializer.class) |
Pavlin Radoslavov | 29a2a88 | 2014-04-08 17:40:54 -0700 | [diff] [blame] | 17 | public final class IPv4Net { |
| 18 | private final IPv4 address; // The IPv4 address |
| 19 | private final short prefixLen; // The prefix length |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 20 | |
| 21 | /** |
| 22 | * Default constructor. |
| 23 | */ |
| 24 | public IPv4Net() { |
Pavlin Radoslavov | 29a2a88 | 2014-04-08 17:40:54 -0700 | [diff] [blame] | 25 | this.address = null; |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 26 | this.prefixLen = 0; |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 27 | } |
| 28 | |
| 29 | /** |
Pavlin Radoslavov | 1bc2c47 | 2013-07-17 18:11:37 -0700 | [diff] [blame] | 30 | * Copy constructor. |
| 31 | * |
| 32 | * @param other the object to copy from. |
| 33 | */ |
| 34 | public IPv4Net(IPv4Net other) { |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 35 | if (other.address != null) { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 36 | this.address = new IPv4(other.address); |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 37 | } else { |
Pavlin Radoslavov | 29a2a88 | 2014-04-08 17:40:54 -0700 | [diff] [blame] | 38 | this.address = null; |
Ray Milkey | b29e626 | 2014-04-09 16:02:14 -0700 | [diff] [blame] | 39 | } |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 40 | this.prefixLen = other.prefixLen; |
Pavlin Radoslavov | 1bc2c47 | 2013-07-17 18:11:37 -0700 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | /** |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 44 | * Constructor for a given address and prefix length. |
| 45 | * |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 46 | * @param address the address to use. |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 47 | * @param prefixLen the prefix length to use. |
| 48 | */ |
| 49 | public IPv4Net(IPv4 address, short prefixLen) { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 50 | this.address = address; |
| 51 | this.prefixLen = prefixLen; |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | /** |
Pavlin Radoslavov | 2013cbb | 2013-02-26 10:15:18 -0800 | [diff] [blame] | 55 | * Constructor from a string. |
| 56 | * |
| 57 | * @param value the value to use. |
| 58 | */ |
| 59 | public IPv4Net(String value) { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 60 | String[] splits = value.split("/"); |
| 61 | if (splits.length != 2) { |
| 62 | throw new IllegalArgumentException("Specified IPv4Net address must contain an IPv4 " + |
| 63 | "address and a prefix length separated by '/'"); |
| 64 | } |
| 65 | this.address = new IPv4(splits[0]); |
| 66 | this.prefixLen = Short.decode(splits[1]); |
Pavlin Radoslavov | 2013cbb | 2013-02-26 10:15:18 -0800 | [diff] [blame] | 67 | } |
| 68 | |
| 69 | /** |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 70 | * Get the address value of the IPv4Net address. |
| 71 | * |
| 72 | * @return the address value of the IPv4Net address. |
| 73 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 74 | public IPv4 address() { |
| 75 | return address; |
| 76 | } |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 77 | |
| 78 | /** |
| 79 | * Get the prefix length value of the IPv4Net address. |
| 80 | * |
| 81 | * @return the prefix length value of the IPv4Net address. |
| 82 | */ |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 83 | public short prefixLen() { |
| 84 | return prefixLen; |
| 85 | } |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 86 | |
| 87 | /** |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 88 | * Convert the IPv4Net value to an "address/prefixLen" string. |
| 89 | * |
| 90 | * @return the IPv4Net value as an "address/prefixLen" string. |
| 91 | */ |
| 92 | @Override |
| 93 | public String toString() { |
Ray Milkey | 269ffb9 | 2014-04-03 14:43:30 -0700 | [diff] [blame] | 94 | return this.address.toString() + "/" + this.prefixLen; |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 95 | } |
Jonathan Hart | 46cc07f | 2014-08-21 18:59:48 -0700 | [diff] [blame] | 96 | |
| 97 | /** |
| 98 | * Compares the value of two IPv4Net objects. |
| 99 | * <p/> |
| 100 | * Note the value of the IPv4 address is compared directly between the |
| 101 | * objects, and must match exactly for the objects to be considered equal. |
| 102 | * This may result in objects which represent the same IP prefix being |
| 103 | * classified as unequal, because the unsignificant bits of the address |
| 104 | * field don't match (the bits to the right of the prefix length). |
| 105 | * <p/> |
| 106 | * TODO Change this behavior so that objects that represent the same prefix |
| 107 | * are classified as equal according to this equals method. |
| 108 | * |
| 109 | * @see Object#equals(Object) |
| 110 | */ |
| 111 | @Override |
| 112 | public boolean equals(Object other) { |
| 113 | if (other == this) { |
| 114 | return true; |
| 115 | } |
| 116 | |
| 117 | if (!(other instanceof IPv4Net)) { |
| 118 | return false; |
| 119 | } |
| 120 | |
| 121 | IPv4Net otherIpv4Net = (IPv4Net) other; |
| 122 | |
| 123 | return Objects.equals(this.address, otherIpv4Net.address) |
| 124 | && this.prefixLen == otherIpv4Net.prefixLen; |
| 125 | } |
| 126 | |
| 127 | @Override |
| 128 | public int hashCode() { |
| 129 | return Objects.hash(address, prefixLen); |
| 130 | } |
Pavlin Radoslavov | 5363c2a | 2013-02-18 09:55:42 -0800 | [diff] [blame] | 131 | } |