com.aoindustries.aoserv.client.validator.DomainLabel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aoserv-client Show documentation
Show all versions of aoserv-client Show documentation
Java client for the AOServ Platform.
/*
* aoserv-client - Java client for the AOServ platform.
* Copyright (C) 2010-2013, 2016 AO Industries, Inc.
* [email protected]
* 7262 Bull Pen Cir
* Mobile, AL 36695
*
* This file is part of aoserv-client.
*
* aoserv-client is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* aoserv-client is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with aoserv-client. If not, see .
*/
package com.aoindustries.aoserv.client.validator;
import com.aoindustries.aoserv.client.AOServObject;
import com.aoindustries.aoserv.client.DtoFactory;
import com.aoindustries.io.FastExternalizable;
import com.aoindustries.io.FastObjectInput;
import com.aoindustries.io.FastObjectOutput;
import com.aoindustries.util.Internable;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInput;
import java.io.ObjectInputValidation;
import java.io.ObjectOutput;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* Represents a DNS domain label (a single part of a domain name between dots). Domain labels must:
*
* - Be non-null
* - Be non-empty
* - Conforms to definition in {@link http://en.wikipedia.org/wiki/DNS_label#Parts_of_a_domain_name}
* - Conforms to rfc2181: {@link http://tools.ietf.org/html/rfc2181#section-11}
* - And allow all numeric as described in {@link http://tools.ietf.org/html/rfc1123#page-13}
*
*
*
* @author AO Industries, Inc.
*/
final public class DomainLabel implements
Comparable,
FastExternalizable,
ObjectInputValidation,
DtoFactory,
Internable
{
public static final int MAX_LENGTH = 63;
/**
* Validates a domain name label.
*/
public static ValidationResult validate(String label) {
if(label==null) return new InvalidResult(ApplicationResources.accessor, "DomainLabel.validate.isNull");
return validate(label, 0, label.length());
}
public static ValidationResult validate(String label, int beginIndex, int endIndex) {
if(label==null) return new InvalidResult(ApplicationResources.accessor, "DomainLabel.validate.isNull");
int len = endIndex-beginIndex;
if(len==0) return new InvalidResult(ApplicationResources.accessor, "DomainLabel.validate.empty");
if(len>MAX_LENGTH) return new InvalidResult(ApplicationResources.accessor, "DomainLabel.validate.tooLong", MAX_LENGTH, len);
for(int pos=beginIndex; pos'z')
&& (ch<'A' || ch>'Z')
&& (ch<'0' || ch>'9')
) return new InvalidResult(ApplicationResources.accessor, "DomainLabel.validate.invalidCharacter", ch, pos-beginIndex);
}
return ValidResult.getInstance();
}
private static final ConcurrentMap interned = new ConcurrentHashMap<>();
public static DomainLabel valueOf(String label) throws ValidationException {
//DomainLabel existing = interned.get(label);
//return existing!=null ? existing : new DomainLabel(label);
return new DomainLabel(label);
}
private String label;
private String lowerLabel;
private DomainLabel(String label) throws ValidationException {
this(label, label.toLowerCase(Locale.ROOT));
}
private DomainLabel(String label, String lowerLabel) throws ValidationException {
this.label = label;
this.lowerLabel = lowerLabel;
validate();
}
private void validate() throws ValidationException {
ValidationResult result = validate(label);
if(!result.isValid()) throw new ValidationException(result);
}
@Override
public boolean equals(Object O) {
return
O!=null
&& O instanceof DomainLabel
&& lowerLabel.equals(((DomainLabel)O).lowerLabel)
;
}
@Override
public int hashCode() {
return lowerLabel.hashCode();
}
@Override
public int compareTo(DomainLabel other) {
return this==other ? 0 : AOServObject.compareIgnoreCaseConsistentWithEquals(label, other.label);
}
@Override
public String toString() {
return label;
}
/**
* Gets the lower-case form of the label. If two different domain labels are
* interned and their toLowerCase is the same String instance, then they are
* equal in case-insensitive manner.
*/
public String toLowerCase() {
return lowerLabel;
}
/**
* Interns this label much in the same fashion as String.intern()
.
*
* @see String#intern()
*/
@Override
public DomainLabel intern() {
try {
DomainLabel existing = interned.get(label);
if(existing==null) {
String internedLabel = label.intern();
String internedLowerLabel = lowerLabel.intern();
DomainLabel addMe = label==internedLabel && lowerLabel==internedLowerLabel ? this : new DomainLabel(internedLabel, lowerLabel);
existing = interned.putIfAbsent(internedLabel, addMe);
if(existing==null) existing = addMe;
}
return existing;
} catch(ValidationException err) {
// Should not fail validation since original object passed
throw new AssertionError(err.getMessage());
}
}
@Override
public com.aoindustries.aoserv.client.dto.DomainLabel getDto() {
return new com.aoindustries.aoserv.client.dto.DomainLabel(label);
}
//
private static final long serialVersionUID = -3692661338685551188L;
public DomainLabel() {
}
@Override
public long getSerialVersionUID() {
return serialVersionUID;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
FastObjectOutput fastOut = FastObjectOutput.wrap(out);
try {
fastOut.writeFastUTF(label);
} finally {
fastOut.unwrap();
}
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
if(label!=null) throw new IllegalStateException();
FastObjectInput fastIn = FastObjectInput.wrap(in);
try {
label = fastIn.readFastUTF();
lowerLabel = label.toLowerCase(Locale.ROOT);
} finally {
fastIn.unwrap();
}
}
@Override
public void validateObject() throws InvalidObjectException {
try {
validate();
} catch(ValidationException err) {
InvalidObjectException newErr = new InvalidObjectException(err.getMessage());
newErr.initCause(err);
throw newErr;
}
}
//
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy