package com.ausregistry.jtoolkit2.se;
import java.util.HashMap;
import java.util.Set;
import javax.xml.xpath.XPathExpressionException;
import com.ausregistry.jtoolkit2.xml.XMLDocument;
/**
* Representation of the EPP check response, as defined in RFC5730. Subclasses
* of this must specify the object to which the command is mapped. Instances of
* this class provide an interface to access availability information for each
* object identified in a {@link com.ausregistry.jtoolkit2.se.CheckCommand}.
* This relies on the instance first being initialised by a suitable EPP check
* response using the method fromXML. For flexibility, this implementation
* extracts the data from the response using XPath queries, the expressions for
* which are defined statically.
*
* @param <I> the type of object identifier used in this check response
*
* @see com.ausregistry.jtoolkit2.se.CheckCommand
*/
public abstract class CheckResponse<I> extends DataResponse {
protected static final String CHKDATA_COUNT_EXPR = "count(" + RES_DATA_EXPR + "/OBJ:chkData/*)";
protected static final String CHKDATA_IND_EXPR = RES_DATA_EXPR + "/OBJ:chkData/OBJ:cd[IDX]";
protected static final String CHKDATA_IDENT_EXPR = "/OBJ:IDENT/text()";
protected static final String CHKDATA_AVAIL_EXPR = "/OBJ:IDENT/@avail";
protected static final String CHKDATA_REASON_EXPR = "/OBJ:reason/text()";
private static final long serialVersionUID = 7769699662780402541L;
private HashMap<I, Availability> availMap;
private boolean[] availArray;
private String[] reasonArray;
public CheckResponse(ObjectType objectType) {
super(StandardCommandType.CHECK, objectType);
availMap = new HashMap<I, Availability>();
}
public boolean isAvailable(final I nameID) {
return (availMap.get(nameID)).isAvail();
}
public String getReason(final I nameID) {
return (availMap.get(nameID)).getReason();
}
public String getReason(int index) {
return reasonArray[index];
}
public Set<I> getNameIDs() {
return availMap.keySet();
}
public boolean[] getAvailableList() {
return availArray;
}
public String[] getReasonList() {
return reasonArray;
}
@Override
public void fromXML(XMLDocument xmlDoc) {
super.fromXML(xmlDoc);
if (!resultArray[0].succeeded()) {
return;
}
try {
int cdCount = xmlDoc.getNodeCount(chkDataCountExpr());
availArray = new boolean[cdCount];
reasonArray = new String[cdCount];
for (int i = 0; i < cdCount; i++) {
String qry = replaceIndex(chkDataIndexExpr(), i + 1);
final I key = getKey(xmlDoc, qry);
String availStr = xmlDoc.getNodeValue(qry + chkDataAvailExpr());
boolean avail = (availStr.equals("1") ? true : false);
availArray[i] = avail;
String reason = xmlDoc.getNodeValue(qry + chkDataReasonExpr());
if (reason != null && reason.length() > 0) {
reasonArray[i] = reason;
}
availMap.put(key, new Availability(avail, reason));
}
} catch (XPathExpressionException xpee) {
maintLogger.warning(xpee.getMessage());
}
}
/**
* Returns an object identifier given an XPath expression for a check data element.
* @param xmlDoc the EPP check response message
* @param qry the XPath query expression
* @return an object identifier
* @throws XPathExpressionException
*/
protected abstract I getKey(final XMLDocument xmlDoc, final String qry)
throws XPathExpressionException;
@Override
public String toString() {
StringBuilder buf = new StringBuilder(super.toString());
for (I name : availMap.keySet()) {
boolean avail = availMap.get(name).isAvail();
String reason = availMap.get(name).getReason();
buf.append("(name = " + name + ")(available = " + avail
+ ")(reason = " + reason + ")");
}
return buf.toString();
}
protected abstract String chkDataCountExpr();
protected abstract String chkDataIndexExpr();
protected abstract String chkDataTextExpr();
protected abstract String chkDataAvailExpr();
protected abstract String chkDataReasonExpr();
}