package com.ausregistry.jtoolkit2.se.secdns;
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.ausregistry.jtoolkit2.se.ExtendedObjectType;
import com.ausregistry.jtoolkit2.xml.XMLDocument;
import com.ausregistry.jtoolkit2.xml.XMLWriter;
/**
* Models the <dsData> element as documented in RFC5910.
*/
public class DSData implements Serializable {
private static final long serialVersionUID = 3729382972073559741L;
private static final String SEC_DNS_PREFIX = ExtendedObjectType.SEC_DNS.getName();
private static final Pattern DIGEST_VALIDATION_PATTERN = Pattern.compile("^[A-Fa-f0-9]+$");
private int keyTag;
private int alg;
private int digestType;
private String digest;
private KeyData keyData;
public DSData() {
}
public DSData(final int keyTagArg, final int algArg, final int digestTypeArg, final String digestArg) {
setKeyTag(keyTagArg);
setAlg(algArg);
setDigestType(digestTypeArg);
setDigest(digestArg);
}
public static final DSData fromXML(final XMLDocument xmlDoc, final String dsDataXPath) throws Exception {
final DSData result = new DSData();
result.setKeyTag(Integer.parseInt(xmlDoc.getNodeValue(dsDataXPath + "/" + SEC_DNS_PREFIX + ":keyTag")));
result.setAlg(Integer.parseInt(xmlDoc.getNodeValue(dsDataXPath + "/" + SEC_DNS_PREFIX + ":alg")));
result.setDigestType(Integer.parseInt(xmlDoc.getNodeValue(dsDataXPath + "/" + SEC_DNS_PREFIX + ":digestType")));
result.setDigest(xmlDoc.getNodeValue(dsDataXPath + "/" + SEC_DNS_PREFIX + ":digest"));
setKeyDataInDSData(xmlDoc, dsDataXPath, result);
return result;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + alg;
result = prime * result + ((digest == null) ? 0 : digest.hashCode());
result = prime * result + digestType;
result = prime * result + keyTag;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DSData other = (DSData) obj;
if (alg != other.alg) {
return false;
}
if (digest == null) {
if (other.digest != null) {
return false;
}
} else if (!digest.equals(other.digest)) {
return false;
}
if (digestType != other.digestType) {
return false;
}
if (keyTag != other.keyTag) {
return false;
}
if (keyData != null && !keyData.equals(other.getKeyData())) {
return false;
}
return true;
}
private static void setKeyDataInDSData(final XMLDocument xmlDoc, final String dsDataXPath,
final DSData result) throws Exception {
final Node tempNode = xmlDoc.getElement(dsDataXPath + "/" + SEC_DNS_PREFIX + ":keyData");
if (tempNode != null) {
result.setKeyData(KeyData.fromXML(xmlDoc, dsDataXPath + "/" + SEC_DNS_PREFIX + ":keyData"));
}
}
public static final void appendDsDataElement(final XMLWriter xmlWriter, final Element parentElement,
final DSData dsData) {
final Element dsDataElement = SecDNSXMLUtil.createElement(xmlWriter, parentElement, "dsData");
SecDNSXMLUtil.appendChildElement(xmlWriter, dsDataElement, "keyTag", dsData.getKeyTag());
SecDNSXMLUtil.appendChildElement(xmlWriter, dsDataElement, "alg", dsData.getAlg());
SecDNSXMLUtil.appendChildElement(xmlWriter, dsDataElement, "digestType", dsData.getDigestType());
SecDNSXMLUtil.appendChildElement(xmlWriter, dsDataElement, "digest", dsData.getDigest());
if (dsData.getKeyData() != null) {
KeyData.appendKeyDataElement(xmlWriter, dsDataElement, dsData.getKeyData());
}
}
public int getKeyTag() {
return keyTag;
}
/**
* @throws IllegalArgumentException if {@code keyTagArg} is outside of the range 0...65535
*/
public void setKeyTag(final int keyTagArg) {
if (keyTagArg < 0) {
throw new IllegalArgumentException();
}
if (keyTagArg > 65535) {
throw new IllegalArgumentException();
}
this.keyTag = keyTagArg;
}
public int getAlg() {
return alg;
}
/**
* @throws IllegalArgumentException if {@code algArg} is outside of the range 0...255
*/
public void setAlg(final int algArg) {
if (algArg < 0) {
throw new IllegalArgumentException();
}
if (algArg > 255) {
throw new IllegalArgumentException();
}
this.alg = algArg;
}
public int getDigestType() {
return digestType;
}
/**
* @throws IllegalArgumentException if {@code digestTypeArg} is outside of the range 0...255
*/
public void setDigestType(final int digestTypeArg) {
if (digestTypeArg < 0) {
throw new IllegalArgumentException();
}
if (digestTypeArg > 255) {
throw new IllegalArgumentException();
}
this.digestType = digestTypeArg;
}
public String getDigest() {
return digest;
}
/**
* @throws IllegalArgumentException if {@code digestArg} does not resemble a valid digest, or if
* the digest has an odd number of characters.
*/
public void setDigest(final String digestArg) {
final Matcher matcher = DIGEST_VALIDATION_PATTERN.matcher(digestArg);
if (matcher.matches() && digestArg.length() % 2 == 0) {
this.digest = digestArg.toUpperCase();
} else {
throw new IllegalArgumentException();
}
}
public KeyData getKeyData() {
return keyData;
}
public void setKeyData(final KeyData keyDataArg) {
this.keyData = keyDataArg;
}
}