package at.gv.egovernment.moa.spss.api.xmlbind;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import at.gv.egovernment.moa.util.Base64Utils;
import at.gv.egovernment.moa.util.Constants;
import at.gv.egovernment.moa.spss.MOAApplicationException;
import at.gv.egovernment.moa.spss.MOASystemException;
import at.gv.egovernment.moa.spss.api.common.Content;
import at.gv.egovernment.moa.spss.api.common.ContentBinary;
import at.gv.egovernment.moa.spss.api.common.ContentXML;
import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult;
import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult;
import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
/**
* Convert a VerifyXMLSignatureResponse
API object into its
* XML representation, according to the MOA XML schema.
*
* @author Patrick Peck
* @version $Id$
*/
public class VerifyXMLSignatureResponseBuilder {
private static final String MOA_NS_URI = Constants.MOA_NS_URI;
/** The XML document containing the response element. */
private Document responseDoc;
/** The response VerifyXMLSignatureResponse
DOM element. */
private Element responseElem;
/**
* Create a new VerifyXMLSignatureResponseBuilder
:
*
* @throws MOASystemException An error occurred setting up the resulting
* XML document.
*/
public VerifyXMLSignatureResponseBuilder() throws MOASystemException {
responseDoc =
ResponseBuilderUtils.createResponse("VerifyXMLSignatureResponse");
responseElem = responseDoc.getDocumentElement();
}
/**
* Build a document containing a VerifyXMLSignatureResponse
* DOM element being the XML representation of the given
* VerifyXMLSignatureResponse
API object.
*
* @param response The VerifyXMLSignatureResponse
to convert
* to XML.
* @return A document containing the VerifyXMLSignatureResponse
* DOM element.
* @throws MOAApplicationException An error occurred building the response.
*/
public Document build(VerifyXMLSignatureResponse response)
throws MOAApplicationException {
Iterator iter;
List responseData;
// add the SignerInfo
ResponseBuilderUtils.addSignerInfo(
responseDoc,
responseElem,
response.getSignerInfo().getSignerCertificate(),
response.getSignerInfo().isQualifiedCertificate(),
response.getSignerInfo().isPublicAuthority(),
response.getSignerInfo().getPublicAuhtorityID());
// add HashInputData elements
responseData = response.getHashInputDatas();
if (responseData != null && !responseData.isEmpty()) {
for (iter = responseData.iterator(); iter.hasNext();) {
Content content = (Content) iter.next();
addContent("HashInputData", content);
}
}
// add ReferenceInputData elements
responseData = response.getReferenceInputDatas();
if (responseData != null && !responseData.isEmpty()) {
for (iter = responseData.iterator(); iter.hasNext();) {
Content content = (Content) iter.next();
addContent("ReferenceInputData", content);
}
}
// add the SignatureCheck
addReferencesCheckResult("SignatureCheck", response.getSignatureCheck());
// add the SignatureManifestCheck
if (response.getSignatureManifestCheck() != null) {
addReferencesCheckResult(
"SignatureManifestCheck",
response.getSignatureManifestCheck());
}
// add the XMLDsigManifestChecks
responseData = response.getXMLDsigManifestChecks();
if (responseData != null && !responseData.isEmpty()) {
for (iter = responseData.iterator(); iter.hasNext();) {
ManifestRefsCheckResult checkResult =
(ManifestRefsCheckResult) iter.next();
addManifestRefsCheckResult("XMLDSIGManifestCheck", checkResult);
}
}
// add the CertificateCheck
ResponseBuilderUtils.addCodeInfoElement(
responseDoc,
responseElem,
"CertificateCheck",
response.getCertificateCheck().getCode(),
response.getCertificateCheck().getInfo());
return responseDoc;
}
/**
* Add an element of type ContentBaseType
to the response.
*
* @param elementName The name of the element.
* @param content The Content
to add. Based on the type of
* the Content
, either a Base64Content
element
* or a XMLContent
subelement will be added. A
* ContentBinary
of type BinaryDataObject
will be
* added as a Base64Content
child element.
* ContentXML
will be added as XMLContent
child
* element.
* @throws MOAApplicationException An error occurred adding the content.
*/
private void addContent(String elementName, Content content)
throws MOAApplicationException {
Element contentElem = responseDoc.createElementNS(MOA_NS_URI, elementName);
switch (content.getContentType()) {
case Content.XML_CONTENT :
ContentXML contentXml = (ContentXML) content;
NodeList nodes = contentXml.getXMLContent();
Element xmlElem;
int i;
xmlElem = responseDoc.createElementNS(MOA_NS_URI, "XMLContent");
//xmlElem.setAttributeNS(XML_NS_URI, "xml:space", "preserve");
xmlElem.setAttribute("xml:space", "preserve");
for (i = 0; i < nodes.getLength(); i++) {
xmlElem.appendChild(responseDoc.importNode(nodes.item(i), true));
}
contentElem.appendChild(xmlElem);
responseElem.appendChild(contentElem);
break;
case Content.BINARY_CONTENT :
Element binaryElem =
responseDoc.createElementNS(MOA_NS_URI, "Base64Content");
ContentBinary contentBinary = (ContentBinary) content;
String base64Str;
try {
base64Str = Base64Utils.encode(contentBinary.getBinaryContent());
} catch (IOException e) {
throw new MOAApplicationException("2200", null, e);
}
binaryElem.appendChild(responseDoc.createTextNode(base64Str));
contentElem.appendChild(binaryElem);
responseElem.appendChild(contentElem);
break;
}
}
/**
* Add a ReferencesCheckResult
to the response.
*
* @param elementName The DOM element name to use.
* @param checkResult The ReferencesCheckResult
to add.
*/
private void addReferencesCheckResult(
String elementName,
ReferencesCheckResult checkResult) {
NodeList info = null;
if (checkResult.getInfo() != null) {
DocumentFragment fragment = responseDoc.createDocumentFragment();
NodeList anyOtherInfo = checkResult.getInfo().getAnyOtherInfo();
int[] failedReferences = checkResult.getInfo().getFailedReferences();
if (anyOtherInfo != null) {
addAnyOtherInfo(fragment, checkResult.getInfo().getAnyOtherInfo());
}
if (failedReferences != null) {
addFailedReferences(fragment, failedReferences);
}
info = fragment.getChildNodes();
}
ResponseBuilderUtils.addCodeInfoElement(
responseDoc,
responseElem,
elementName,
checkResult.getCode(),
info);
}
/**
* Add a ManifestRefsCheckResult
to the response.
*
* @param elementName The DOM element name to use.
* @param checkResult The ManifestRefsCheckResult
to add.
*/
private void addManifestRefsCheckResult(
String elementName,
ManifestRefsCheckResult checkResult) {
DocumentFragment fragment = responseDoc.createDocumentFragment();
NodeList anyOtherInfo = checkResult.getInfo().getAnyOtherInfo();
int[] failedReferences = checkResult.getInfo().getFailedReferences();
Element referringSigRefElem;
String referringSigRefStr;
// add any other elements
if (anyOtherInfo != null) {
addAnyOtherInfo(fragment, checkResult.getInfo().getAnyOtherInfo());
}
// add the failed references
if (failedReferences != null) {
addFailedReferences(fragment, failedReferences);
}
// add the ReferringSigReference
referringSigRefElem =
responseDoc.createElementNS(MOA_NS_URI, "ReferringSigReference");
referringSigRefStr =
Integer.toString(checkResult.getInfo().getReferringSignatureReference());
referringSigRefElem.appendChild(
responseDoc.createTextNode(referringSigRefStr));
fragment.appendChild(referringSigRefElem);
// add XMLDSIGManifestCheckResult to the response
ResponseBuilderUtils.addCodeInfoElement(
responseDoc,
responseElem,
elementName,
checkResult.getCode(),
fragment.getChildNodes());
}
/**
* Add arbitrary XML content to a DOM DocumentFragment
.
*
* @param fragment The fragment to add the XML content to.
* @param anyOtherInfo The XML content to add.
*/
private void addAnyOtherInfo(
DocumentFragment fragment,
NodeList anyOtherInfo) {
int i;
for (i = 0; i < anyOtherInfo.getLength(); i++) {
fragment.appendChild(responseDoc.importNode(anyOtherInfo.item(i), true));
}
}
/**
* Add the failed references as FailedReference
DOM elements to
* the fragment.
*
* @param fragment The DOM document fragment to add the
* FailedReference
elements to.
* @param failedReferences The indexes of the failed references.
*/
private void addFailedReferences(
DocumentFragment fragment,
int[] failedReferences) {
Element failedReferenceElem;
int i;
for (i = 0; i < failedReferences.length; i++) {
failedReferenceElem =
responseDoc.createElementNS(MOA_NS_URI, "FailedReference");
failedReferenceElem.appendChild(
responseDoc.createTextNode(Integer.toString(failedReferences[i])));
fragment.appendChild(failedReferenceElem);
}
}
}