/*
* 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.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Element;
import org.w3c.dom.traversal.NodeIterator;
import at.gv.egovernment.moa.spss.MOAApplicationException;
import at.gv.egovernment.moa.spss.api.SPSSFactory;
import at.gv.egovernment.moa.spss.api.cmssign.CreateCMSSignatureRequest;
import at.gv.egovernment.moa.spss.api.cmssign.DataObjectInfo;
import at.gv.egovernment.moa.spss.api.cmssign.SingleSignatureInfo;
import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent;
import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject;
import at.gv.egovernment.moa.spss.api.common.MetaInfo;
import at.gv.egovernment.moaspss.util.Base64Utils;
import at.gv.egovernment.moaspss.util.BoolUtils;
import at.gv.egovernment.moaspss.util.Constants;
import at.gv.egovernment.moaspss.util.DOMUtils;
import at.gv.egovernment.moaspss.util.XPathUtils;
/**
* A parser to parse CreateCMSSignatureRequest
DOM trees into
* CreateCMSSignatureRequest
API objects.
*
* @author Patrick Peck
* @version $Id$
*/
public class CreateCMSSignatureRequestParser {
//
// XPath expresssions to select elements in the CreateCMSSignatureRequest
//
private static final String MOA = Constants.MOA_PREFIX + ":";
private static final String KEY_IDENTIFIER_XPATH =
"/" + MOA + "CreateCMSSignatureRequest/" + MOA + "KeyIdentifier";
private static final String SINGLE_SIGNATURE_INFO_XPATH =
"/" + MOA + "CreateCMSSignatureRequest/" + MOA + "SingleSignatureInfo";
private static final String DATA_OBJECT_INFO_XPATH = MOA + "DataObjectInfo";
private static final String DATA_OBJECT_XPATH = MOA + "DataObject";
private static final String SL_CONFORM_ATTR_NAME = "SecurityLayerConformity";
private static final String IS_PADES_SIGNATURE_ATTR_NAME = "PAdESConformity";
private static final String META_INFO_XPATH = MOA + "MetaInfo";
private static final String CONTENT_XPATH = MOA + "Content";
private static final String BASE64_CONTENT_XPATH = MOA + "Base64Content";
private static final String EXCLUDEBYTERANGE_FROM_XPATH = MOA + "ExcludedByteRange/" + MOA + "From";
private static final String EXCLUDEBYTERANGE_TO_XPATH = MOA + "ExcludedByteRange/" + MOA + "To";
/** The factory to create API objects. */
private final SPSSFactory factory;
/**
* Create a new CreateCMSSignatureRequestParser
.
*/
public CreateCMSSignatureRequestParser() {
this.factory = SPSSFactory.getInstance();
}
/**
* Parse a CreateCMSSignatureRequest
DOM element, as defined by the
* MOA schema.
*
* @param requestElem The CreateCMSSignatureRequest
to parse. The
* request must have been successfully parsed against the
* schema for this method to succeed.
* @return A CreateCMSSignatureRequest
API object containing the
* data from the DOM element.
* @throws MOAApplicationException An error occurred parsing the request.
*/
public CreateCMSSignatureRequest parse(Element requestElem)
throws MOAApplicationException {
final List singleSignatureInfos = parseSingleSignatureInfos(requestElem);
final String keyIdentifier =
XPathUtils.getElementValue(requestElem, KEY_IDENTIFIER_XPATH, null);
return factory.createCreateCMSSignatureRequest(
keyIdentifier,
singleSignatureInfos);
}
/**
* Parse all SingleSignatureInfo
elements of the
* CreateCMSSignatureRequest
.
*
* @param requestElem The CreateCMSSignatureRequest
to parse.
* @return A List
of SingleSignatureInfo
API objects.
* @throws MOAApplicationException An error occurred parsing on of the
* SingleSignatureInfo
elements.
*/
private List parseSingleSignatureInfos(Element requestElem)
throws MOAApplicationException {
final List singleSignatureInfos = new ArrayList();
final NodeIterator sigInfoElems =
XPathUtils.selectNodeIterator(requestElem, SINGLE_SIGNATURE_INFO_XPATH);
Element sigInfoElem;
while ((sigInfoElem = (Element) sigInfoElems.nextNode()) != null) {
singleSignatureInfos.add(parseSingleSignatureInfo(sigInfoElem));
}
return singleSignatureInfos;
}
/**
* Parse a SingleSignatureInfo
DOM element.
*
* @param sigInfoElem The SingleSignatureInfo
DOM element to parse.
* @return A SingleSignatureInfo
API object containing the
* information of sigInfoElem
.
* @throws MOAApplicationException An error occurred parsing the
* SingleSignatureInfo
.
*/
private SingleSignatureInfo parseSingleSignatureInfo(Element sigInfoElem)
throws MOAApplicationException {
final DataObjectInfo dataObjectInfo = parseDataObjectInfo(sigInfoElem);
boolean securityLayerConform;
boolean isPAdESSignature = false;
if (sigInfoElem.hasAttribute(SL_CONFORM_ATTR_NAME)) {
securityLayerConform =
BoolUtils.valueOf(sigInfoElem.getAttribute(SL_CONFORM_ATTR_NAME));
} else {
securityLayerConform = true;
}
if (sigInfoElem.hasAttribute(IS_PADES_SIGNATURE_ATTR_NAME)) {
isPAdESSignature = BoolUtils.valueOf(sigInfoElem.getAttribute(IS_PADES_SIGNATURE_ATTR_NAME));
}
return factory.createSingleSignatureInfoCMS(
dataObjectInfo,
securityLayerConform,
isPAdESSignature);
}
/**
* Parse the DataObjectInfo
DOM elements contained in the given
* SingleSignatureInfo
DOM element.
*
* @param sigInfoElem The SingleSignatureInfo
DOM element whose
* DataObjectInfo
s to parse.
* @return A List
of DataObjectInfo
API objects
* containing the data from the DataObjectInfo
DOM
* elements.
* @throws MOAApplicationException An error occurred parsing one of the
* DataObjectInfo
s.
*/
private DataObjectInfo parseDataObjectInfo(Element sigInfoElem)
throws MOAApplicationException {
final Element dataObjInfoElem = (Element) XPathUtils.selectSingleNode(sigInfoElem,
DATA_OBJECT_INFO_XPATH);
final String structure = dataObjInfoElem.getAttribute("Structure");
final Element dataObjectElem =
(Element) XPathUtils.selectSingleNode(dataObjInfoElem, DATA_OBJECT_XPATH);
final CMSDataObject dataObject = parseDataObject(dataObjectElem);
return factory.createDataObjectInfo(
structure,
dataObject);
}
/**
* Parse a the DataObject
DOM element contained in a given
* CreateCMSSignatureRequest
DOM element.
*
* @param requestElem The DataObject DOM element of the
* VerifyCMSSignatureRequest
to parse.
* @return The CMSDataObject
API object containing the data from
* the DataObject
DOM element.
*/
private CMSDataObject parseDataObject(Element dataObjectElem) {
if (dataObjectElem != null) {
final Element metaInfoElem = (Element) XPathUtils.selectSingleNode(dataObjectElem, META_INFO_XPATH);
MetaInfo metaInfo = null;
final Element contentElem = (Element) XPathUtils.selectSingleNode(dataObjectElem, CONTENT_XPATH);
final CMSContent content = parseContent(contentElem);
if (metaInfoElem != null) {
metaInfo = RequestParserUtils.parseMetaInfo(metaInfoElem);
}
final String excludeByteRangeFromStr = XPathUtils.getElementValue(dataObjectElem,
EXCLUDEBYTERANGE_FROM_XPATH, null);
final String excludeByteRangeToStr = XPathUtils.getElementValue(dataObjectElem,
EXCLUDEBYTERANGE_TO_XPATH, null);
BigDecimal excludeByteRangeFrom = null;
BigDecimal excludeByteRangeTo = null;
if (excludeByteRangeFromStr != null) {
excludeByteRangeFrom = new BigDecimal(excludeByteRangeFromStr);
}
if (excludeByteRangeToStr != null) {
excludeByteRangeTo = new BigDecimal(excludeByteRangeToStr);
}
return factory.createCMSDataObject(metaInfo, content, excludeByteRangeFrom, excludeByteRangeTo);
} else {
return null;
}
}
/**
* Parse the content contained in a CMSContentBaseType
kind of DOM
* element.
*
* @param contentElem The CMSContentBaseType
kind of element to
* parse.
* @return A CMSDataObject
API object containing the data from the
* given DOM element.
*/
private CMSContent parseContent(Element contentElem) {
final Element base64ContentElem =
(Element) XPathUtils.selectSingleNode(contentElem, BASE64_CONTENT_XPATH);
if (base64ContentElem != null) {
final String base64Str = DOMUtils.getText(base64ContentElem);
final InputStream binaryContent = Base64Utils.decodeToStream(base64Str, true);
return factory.createCMSContent(binaryContent);
} else {
return factory.createCMSContent(
contentElem.getAttribute("Reference"));
}
}
}