/*
* Copyright 2003 Federal Chancellery Austria
* MOA-SPSS has been developed in a cooperation between BRZ, the Federal
* Chancellery Austria - ICT staff unit, and Graz University of Technology.
*
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
* the European Commission - subsequent versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
* http://www.osor.eu/eupl/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*
* This product combines work with different licenses. See the "NOTICE" text
* file for details on the various modules and licenses.
* The "NOTICE" text file is part of the distribution. Any derivative works
* that you distribute must include a readable copy of the "NOTICE" text file.
*/
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.moaspss.logging.Logger;
import at.gv.egovernment.moaspss.util.Base64Utils;
import at.gv.egovernment.moaspss.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.common.InputData;
import at.gv.egovernment.moa.spss.api.xmlverify.AdESFormResults;
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;
import at.gv.egovernment.moa.spss.server.config.ConfigurationException;
import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
/**
* 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;
private boolean includeSigningTime = false;
/**
* 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();
}
public VerifyXMLSignatureResponseBuilder(Document responseDoc, String name, boolean includeSigningTime) throws MOASystemException {
this.responseDoc = responseDoc;
responseElem = responseDoc.createElementNS(MOA_NS_URI, name);
this.includeSigningTime = includeSigningTime;
}
public Element buildElement(VerifyXMLSignatureResponse response) throws MOAApplicationException {
this.build(response);
return responseElem;
}
/**
* 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().getQCSource(),
response.getSignerInfo().isPublicAuthority(), response.getSignerInfo().getPublicAuhtorityID(),
response.getSignerInfo().isSSCD(), response.getSignerInfo().getSSCDSource(),
response.getSignerInfo().getIssuerCountryCode(),
response.getSignerInfo().getTslInfos());
if(this.includeSigningTime) {
ResponseBuilderUtils.addSigningTime(responseDoc,
responseElem, response.getSignerInfo().getSigningTime());
}
// add HashInputData elements
responseData = response.getHashInputDatas();
if (responseData != null && !responseData.isEmpty()) {
for (iter = responseData.iterator(); iter.hasNext();) {
InputData inputData = (InputData) iter.next();
addContent("HashInputData", inputData);
}
}
// add ReferenceInputData elements
responseData = response.getReferenceInputDatas();
if (responseData != null && !responseData.isEmpty()) {
for (iter = responseData.iterator(); iter.hasNext();) {
InputData inputData = (InputData) iter.next();
addContent("ReferenceInputData", inputData);
}
}
// 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());
if (response.getAdESFormResults() != null) {
Iterator formIterator = response.getAdESFormResults().iterator();
while (formIterator.hasNext()) {
AdESFormResults adESFormResult = (AdESFormResults) formIterator.next();
// add the CertificateCheck
ResponseBuilderUtils.addFormCheckElement(responseDoc, responseElem, "FormCheckResult",
adESFormResult.getCode().intValue(), adESFormResult.getName());
}
}
if(response.getExtendedCertificateCheck() != null) {
ResponseBuilderUtils.addExtendendResult(responseDoc, responseElem, response.getExtendedCertificateCheck());
}
return responseDoc;
}
/**
* Add an element of type ContentBaseType
to the response.
*
* @param elementName
* The name of the element.
*
* @param inputData
* The InputData
to add. Based on the type of
*
* the InputData
, either a
* Base64Content
element or a
* XMLContent
subelement will be added. An
* InputDataBinaryImpl
will be added as a Base64Content
* child element. AnInputDataXMLImpl
will be added
* as
* XMLContent
child element.
*
* @throws MOAApplicationException
* An error occurred adding the content.
*/
private void addContent(String elementName, InputData inputData) throws MOAApplicationException {
Element contentElem = responseDoc.createElementNS(MOA_NS_URI, elementName);
contentElem.setAttributeNS(null, "PartOf", inputData.getPartOf());
if (inputData.getReferringReferenceNumber() != InputData.REFERER_NONE_)
contentElem.setAttributeNS(null, "ReferringSigReference",
Integer.toString(inputData.getReferringReferenceNumber()));
switch (inputData.getContentType()) {
case Content.XML_CONTENT:
ContentXML contentXml = (ContentXML) inputData;
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) inputData;
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);
}
}
}