All Downloads are FREE. Search and download functionalities are using the official Maven repository.

inet.ipaddr.IPAddressStringParameters Maven / Gradle / Ivy

There is a newer version: 5.5.1
Show newest version
/*
 * Copyright 2016-2018 Sean C Foley
 *
 * 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
 *     or at
 *     https://github.com/seancfoley/IPAddress/blob/master/LICENSE
 *
 * 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 inet.ipaddr;

import inet.ipaddr.IPAddress.IPVersion;
import inet.ipaddr.ipv4.IPv4AddressStringParameters;
import inet.ipaddr.ipv6.IPv6AddressStringParameters;

/**
 * This class allows you to control the validation performed by the class {@link IPAddressString}.
 * 
 * The {@link IPAddressString} class uses a default permissive IPAddressStringParameters instance when you do not specify one.
 * 
 * If you wish to use parameters different from the default, then use this class.  All instances are immutable and must be constructed with the nested Builder class.
 * 
 * @author sfoley
 *
 */
public class IPAddressStringParameters extends AddressStringParameters implements Comparable {
	
	private static final long serialVersionUID = 4L;

	//The defaults are permissive
	//One thing to note: since zones are allowed by default, the % character is interpreted as a zone, not as an SQL wildcard.
	//Also, since inet_aton style is allowed by default, leading zeros in ipv4 are interpreted as octal.
	//
	//If you wish to deviate from the default options,
	//you can simply pass in your own IPAddressStringParameters and HostNameParameters options to the respective constructors.
	//To standardize, you can subclass HostName and/or IPAddressString to use your own standard defaults in the constructors that take validation options.
	//Optionally, you can let everything parse successfully and then validate the resulting HostName/IPAddressString/IPAddress objects according to your taste.
	
	public static final boolean DEFAULT_ALLOW_PREFIX_ONLY = true;
	public static final boolean DEFAULT_EMPTY_IS_LOOPBACK = true; //Note that with InetAddress, empty strings are interpreted as the loopback address
	public static final boolean DEFAULT_ALLOW_PREFIX = true;
	public static final boolean DEFAULT_ALLOW_MASK = true;
	public static final boolean DEFAULT_ALLOW_IPV4 = true;
	public static final boolean DEFAULT_ALLOW_IPV6 = true;
	
	/**
	 * Allows addresses like /64 which are only prefix lenths.
	 * Such addresses are interpreted as the network mask for the given prefix length.
	 * @see #DEFAULT_ALLOW_PREFIX_ONLY
	 */
	public final boolean allowPrefixOnly;

	/**
	 * Whether the zero-length address is interpreted as the loopback.
	 * @see #allowEmpty
	 * @see #DEFAULT_EMPTY_IS_LOOPBACK
	 */
	public final boolean emptyIsLoopback;
	
	/**
	 * Allows addresses with prefix length like 1.2.0.0/16
	 * Such as an address is interpreted as a subnet.
	 * 1.2.0.0/16 is the subnet of addresses with network prefix 1.2
	 * 
	 * @see #DEFAULT_ALLOW_PREFIX
	 */
	public final boolean allowPrefix;
	
	/**
	 * Allows masks to follow valid addresses, such as 1.2.3.4/255.255.0.0 which has the mask 255.255.0.0

* If the mask is the mask for a network prefix length, this is interpreted as the subnet for that network prefix length. * Otherwise the address is simply masked by the mask. * For instance, 1.2.3.4/255.0.255.0 is 1.0.3.0, while 1.2.3.4/255.255.0.0 is 1.2.0.0/16. * * @see #allowPrefix * @see #DEFAULT_ALLOW_MASK * */ public final boolean allowMask; public final boolean allowIPv6; public final boolean allowIPv4; private IPv6AddressStringParameters ipv6Options; private IPv4AddressStringParameters ipv4Options; public IPVersion inferVersion() { if(allowIPv6) { if(!allowIPv4) { return IPVersion.IPV6; } } else { if(allowIPv4) { return IPVersion.IPV4; } } return null; } public static class Builder extends AddressStringParameters.BuilderBase { private boolean emptyIsLoopback = DEFAULT_EMPTY_IS_LOOPBACK; private boolean allowPrefix = DEFAULT_ALLOW_PREFIX; private boolean allowMask = DEFAULT_ALLOW_MASK; private boolean allowPrefixOnly = DEFAULT_ALLOW_PREFIX_ONLY; private boolean allowIPv4 = DEFAULT_ALLOW_IPV4; private boolean allowIPv6 = DEFAULT_ALLOW_IPV6; //private boolean noIpv4Params, noIpv6Params; IPv4AddressStringParameters.Builder ipv4Builder; static private IPv4AddressStringParameters DEFAULT_IPV4_OPTS = new IPv4AddressStringParameters.Builder().toParams(); IPv6AddressStringParameters.Builder ipv6Builder; static private IPv6AddressStringParameters DEFAULT_IPV6_OPTS = new IPv6AddressStringParameters.Builder().toParams(); HostNameParameters.Builder parent; public Builder() {} public HostNameParameters.Builder getParentBuilder() { return parent; } /** * @see IPAddressStringParameters#allowEmpty * @param allow * @return the builder */ @Override public Builder allowEmpty(boolean allow) { return (Builder) super.allowEmpty(allow); } @Override public Builder allowSingleSegment(boolean allow) { return (Builder) super.allowSingleSegment(allow); } public Builder setEmptyAsLoopback(boolean bool) { emptyIsLoopback = bool; return this; } public Builder allowPrefix(boolean allow) { allowPrefix = allow; return this; } public Builder allowMask(boolean allow) { allowMask = allow; return this; } public Builder allowPrefixOnly(boolean allow) { allowPrefixOnly = allow; return this; } @Override public Builder allowAll(boolean allow) { return (Builder) super.allowAll(allow); } public Builder allowIPv4(boolean allow) { allowIPv4 = allow; return this; } public Builder allowIPv6(boolean allow) { allowIPv6 = allow; return this; } public Builder allowWildcardedSeparator(boolean allow) { getIPv4AddressParametersBuilder().allowWildcardedSeparator(allow); getIPv6AddressParametersBuilder().allowWildcardedSeparator(allow); return this; } public Builder setRangeOptions(RangeParameters rangeOptions) { getIPv4AddressParametersBuilder().setRangeOptions(rangeOptions); getIPv6AddressParametersBuilder().setRangeOptions(rangeOptions); return this; } public Builder allow_inet_aton(boolean allow) { getIPv4AddressParametersBuilder().allow_inet_aton(allow); getIPv6AddressParametersBuilder().allow_mixed_inet_aton(allow); return this; } /** * Replaces all existing IPv6 parameters with the ones in the supplied parameters instance. */ public void setIPv6AddressParameters(IPv6AddressStringParameters params) { ipv6Builder = params.toBuilder(); } /** * Get the sub-builder for setting IPv6 parameters. * @return the IPv6 builder */ public IPv6AddressStringParameters.Builder getIPv6AddressParametersBuilder() { if(ipv6Builder == null) { ipv6Builder = new IPv6AddressStringParameters.Builder(); } ((IPAddressStringFormatParameters.BuilderBase) ipv6Builder).parent = this; return ipv6Builder; } /** * Replaces all existing IPv4 parameters with the ones in the supplied parameters instance. */ public void setIPv4AddressParameters(IPv4AddressStringParameters params) { ipv4Builder = params.toBuilder(); } /** * Get the sub-builder for setting IPv4 parameters. * @return the IPv4 builder */ public IPv4AddressStringParameters.Builder getIPv4AddressParametersBuilder() { if(ipv4Builder == null) { ipv4Builder = new IPv4AddressStringParameters.Builder(); } ((IPAddressStringFormatParameters.BuilderBase) ipv4Builder).parent = this; return ipv4Builder; } public IPAddressStringParameters toParams() { IPv4AddressStringParameters ipv4Opts; if(ipv4Builder == null) { ipv4Opts = DEFAULT_IPV4_OPTS; } else { ipv4Opts = ipv4Builder.toParams(); } IPv6AddressStringParameters ipv6Opts; if(ipv6Builder == null) { ipv6Opts = DEFAULT_IPV6_OPTS; } else { ipv6Opts = ipv6Builder.toParams(); } return new IPAddressStringParameters(allowEmpty, allowAll, allowSingleSegment, emptyIsLoopback, allowPrefix, allowMask, allowPrefixOnly, allowIPv4, allowIPv6, ipv4Opts, ipv6Opts); } } public abstract static class IPAddressStringFormatParameters extends AddressStringFormatParameters { private static final long serialVersionUID = 4L; public static final boolean DEFAULT_ALLOW_PREFIX_LENGTH_LEADING_ZEROS = true; public static final boolean DEFAULT_ALLOW_PREFIX_BEYOND_ADDRESS_SIZE = false; /** * controls whether ipv4 can have prefix length bigger than 32 and whether ipv6 can have prefix length bigger than 128 * @see #DEFAULT_ALLOW_PREFIX_BEYOND_ADDRESS_SIZE */ public final boolean allowPrefixesBeyondAddressSize; /** * controls whether you allow addresses with prefixes that have leasing zeros like 1.0.0.0/08 or 1::/064 * * @see #DEFAULT_ALLOW_PREFIX_LENGTH_LEADING_ZEROS */ public final boolean allowPrefixLengthLeadingZeros; public IPAddressStringFormatParameters( boolean allowLeadingZeros, boolean allowPrefixLengthLeadingZeros, boolean allowUnlimitedLeadingZeros, RangeParameters rangeOptions, boolean allowWildcardedSeparator, boolean allowPrefixesBeyondAddressSize) { super(allowLeadingZeros, allowUnlimitedLeadingZeros, rangeOptions, allowWildcardedSeparator); this.allowPrefixLengthLeadingZeros = allowPrefixLengthLeadingZeros; this.allowPrefixesBeyondAddressSize = allowPrefixesBeyondAddressSize; } protected BuilderBase toBuilder(BuilderBase builder) { super.toBuilder(builder); builder.allowPrefixLengthLeadingZeros = allowPrefixLengthLeadingZeros; builder.allowPrefixesBeyondAddressSize = allowPrefixesBeyondAddressSize; return builder; } protected static class BuilderBase extends AddressStringFormatParameters.BuilderBase { protected boolean allowPrefixesBeyondAddressSize = DEFAULT_ALLOW_PREFIX_BEYOND_ADDRESS_SIZE; protected boolean allowPrefixLengthLeadingZeros = DEFAULT_ALLOW_PREFIX_LENGTH_LEADING_ZEROS; IPAddressStringParameters.Builder parent; public IPAddressStringParameters.Builder getParentBuilder() { return parent; } @Override public BuilderBase setRangeOptions(RangeParameters rangeOptions) { return (BuilderBase) super.setRangeOptions(rangeOptions); } public BuilderBase allowPrefixesBeyondAddressSize(boolean allow) { allowPrefixesBeyondAddressSize = allow; return this; } @Override public BuilderBase allowWildcardedSeparator(boolean allow) { return (BuilderBase) super.allowWildcardedSeparator(allow); } @Override public BuilderBase allowLeadingZeros(boolean allow) { return (BuilderBase) super.allowLeadingZeros(allow); } public BuilderBase allowPrefixLengthLeadingZeros(boolean allow) { allowPrefixLengthLeadingZeros = allow; return this; } @Override public BuilderBase allowUnlimitedLeadingZeros(boolean allow) { return (BuilderBase) super.allowUnlimitedLeadingZeros(allow); } } public abstract IPAddressNetwork getNetwork(); protected int compareTo(IPAddressStringFormatParameters o) { int result = super.compareTo(o); if(result == 0) { result = Boolean.compare(allowPrefixesBeyondAddressSize, o.allowPrefixesBeyondAddressSize); if(result == 0) { result = Boolean.compare(allowPrefixLengthLeadingZeros, o.allowPrefixLengthLeadingZeros); } } return result; } @Override public boolean equals(Object o) { if(o instanceof IPAddressStringFormatParameters) { IPAddressStringFormatParameters other = (IPAddressStringFormatParameters) o; return super.equals(o) && allowPrefixesBeyondAddressSize == other.allowPrefixesBeyondAddressSize && allowPrefixLengthLeadingZeros == other.allowPrefixLengthLeadingZeros; } return false; } @Override public int hashCode() { int hash = super.hashCode(); if(allowPrefixesBeyondAddressSize) { hash |= 0x8;//reuse the 4th bit } return hash; } } public Builder toBuilder() { return toBuilder(false); } public Builder toBuilder(boolean isMixed) { Builder builder = new Builder(); super.toBuilder(builder); builder.allowPrefixOnly = allowPrefixOnly; builder.emptyIsLoopback = emptyIsLoopback; builder.allowPrefix = allowPrefix; builder.allowMask = allowMask; builder.allowIPv6 = allowIPv6; builder.allowIPv4 = allowIPv4; builder.ipv4Builder = ipv4Options.toBuilder(); builder.ipv6Builder = ipv6Options.toBuilder(isMixed); builder.allowSingleSegment = allowSingleSegment; builder.allowEmpty = allowEmpty; builder.allowAll = allowAll; return builder; } public IPAddressStringParameters( boolean allowEmpty, boolean allowAll, boolean allowSingleSegment, boolean emptyIsLoopback, boolean allowPrefix, boolean allowMask, boolean allowPrefixOnly, boolean allowIPv4, boolean allowIPv6, IPv4AddressStringParameters ipv4Options, IPv6AddressStringParameters ipv6Options) { super(allowEmpty, allowAll, allowSingleSegment); this.allowPrefixOnly = allowPrefixOnly; this.emptyIsLoopback = emptyIsLoopback; this.allowPrefix = allowPrefix; this.allowMask = allowMask; this.allowIPv4 = allowIPv4; this.allowIPv6 = allowIPv6; this.ipv6Options = ipv6Options; this.ipv4Options = ipv4Options; } public IPv6AddressStringParameters getIPv6Parameters() { return ipv6Options; } public IPv4AddressStringParameters getIPv4Parameters() { return ipv4Options; } @Override public IPAddressStringParameters clone() { IPAddressStringParameters result = (IPAddressStringParameters) super.clone(); result.ipv4Options = ipv4Options.clone(); result.ipv6Options = ipv6Options.clone(); return result; } @Override public int compareTo(IPAddressStringParameters o) { int result = super.compareTo(o); if(result == 0) { result = ipv4Options.compareTo(o.ipv4Options); if(result == 0) { result = ipv6Options.compareTo(o.ipv6Options); if(result == 0) { result = Boolean.compare(emptyIsLoopback, o.emptyIsLoopback); if(result == 0) { result = Boolean.compare(allowPrefix, o.allowPrefix); if(result == 0) { result = Boolean.compare(allowMask, o.allowMask); if(result == 0) { result = Boolean.compare(allowIPv6, o.allowIPv6); if(result == 0) { result = Boolean.compare(allowIPv4, o.allowIPv4); } } } } } } } return result; } @Override public boolean equals(Object o) { if(o instanceof IPAddressStringParameters) { IPAddressStringParameters other = (IPAddressStringParameters) o; return super.equals(o) && ipv4Options.equals(other.ipv4Options) && ipv6Options.equals(other.ipv6Options) && emptyIsLoopback == other.emptyIsLoopback && allowPrefix == other.allowPrefix && allowMask == other.allowMask && allowIPv6 == other.allowIPv6 && allowIPv4 == other.allowIPv4; } return false; } @Override public int hashCode() { //the ipv4 part uses just one byte and one additional bit int hash = ipv4Options.hashCode(); //the ipv6 part uses 2 bytes plus two extra bit hash |= ipv6Options.hashCode() << 9; //so now we are up to 3 bytes and 3 additional bits, so we have 0x8000000 and onwards available if(emptyIsLoopback) { hash |= 0x8000000; } if(allowPrefix) { hash |= 0x10000000; } if(allowMask) { hash |= 0x20000000; } if(allowEmpty) { hash |= 0x40000000; } if(allowSingleSegment) { hash |= 0x80000000; } //no more bits available // if(allowAll) { // hash |= 0x100000000; // } return hash; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy