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); } } }