package at.gv.egovernment.moa.spss.api.xmlbind; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.w3c.dom.Element; import org.w3c.dom.traversal.NodeIterator; import at.gv.egovernment.moa.util.Base64Utils; import at.gv.egovernment.moa.util.Constants; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.util.XPathUtils; import at.gv.egovernment.moa.spss.MOAApplicationException; import at.gv.egovernment.moa.spss.api.SPSSFactory; import at.gv.egovernment.moa.spss.api.common.MetaInfo; import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation; import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile; import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation; import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfo; import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile; import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile; import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter; import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile; /** * Parse the various profile elements contained in the MOA web service requests * and given as separate files in the MOA configuration. * * The profiles parsed must be schema valid according to the MOA XML schema. * * @author Patrick Peck * @version $Id$ */ public class ProfileParser { // // XPath expressions to select parts of the profiles // private static final String MOA = Constants.MOA_PREFIX + ":"; private static final String DSIG = Constants.DSIG_PREFIX + ":"; private static final String CREATE_TRANSFORMS_XPATH = MOA + "CreateTransformsInfo/" + DSIG + "Transforms"; private static final String FINAL_DATA_META_INFO_XPATH = MOA + "CreateTransformsInfo/" + MOA + "FinalDataMetaInfo"; private static final String CREATE_SIGNATURE_LOCATION_XPATH = MOA + "CreateSignatureLocation"; private static final String SUPPLEMENT_XPATH = MOA + "Supplement"; private static final String VERIFY_TRANSFORMS_XPATH = DSIG + "Transforms"; private static final String TRANSFORM_PARAMETER_XPATH = MOA + "TransformParameter"; private static final String TRANSFORM_PARAMETER_CONTENT_XPATH = MOA + "Base64Content | " + MOA + "Hash"; private static final String DIGEST_METHOD_XPATH = DSIG + "DigestMethod"; private static final String DIGEST_VALUE_XPATH = DSIG + "DigestValue"; /** The factory used to create API objects. */ private SPSSFactory factory = SPSSFactory.getInstance(); /** * Parse a CreateTransformsInfoProfile DOM element. * * @param profileElem The CreateTransformsInfoProfile element * to parse. * @return The CreateTransformsInfoProfile API object containing * the data from the profileElem. * @throws MOAApplicationException An error occurred parsing the DOM element. */ public CreateTransformsInfoProfile parseCreateTransformsInfoProfile(Element profileElem) throws MOAApplicationException { CreateTransformsInfo createTransformsInfo = parseCreateTransformsInfo(profileElem); List supplements = parseSupplements(profileElem); return factory.createCreateTransformsInfoProfile( createTransformsInfo, supplements); } /** * Parse the CreateTransformsInfo DOM element contained in a * CreateTransformsInfoProfile. * * @param profileElem The CreateTransformsInfoProfile DOM * element containing the CreateTransformsInfo. * @return The CreateTransformsInfo API object containinig the * data from the CreateTransformsInfo DOM element. * @throws MOAApplicationException An error occurred parsing the * CreateTransformsInfo DOM element. */ private CreateTransformsInfo parseCreateTransformsInfo(Element profileElem) throws MOAApplicationException { Element transformsElem = (Element) XPathUtils.selectSingleNode( profileElem, CREATE_TRANSFORMS_XPATH); Element metaInfoElem = (Element) XPathUtils.selectSingleNode( profileElem, FINAL_DATA_META_INFO_XPATH); MetaInfo finalDataMetaInfo; List transforms; // parse the dsig:Transforms if (transformsElem != null) { TransformParser transformsParser = new TransformParser(); transforms = transformsParser.parseTransforms(transformsElem); } else { transforms = null; } // parse the meta info finalDataMetaInfo = RequestParserUtils.parseMetaInfo(metaInfoElem); return factory.createCreateTransformsInfo(transforms, finalDataMetaInfo); } /** * Parse a CreateSignatureEnvironmentProfile DOM element. * * @param profileElem The CreateSignatureEnvironmentProfile * DOM element to parse. * @return The CreateSignatureEnvironmentProfile API object * containing the data from the profileElem. */ public CreateSignatureEnvironmentProfile parseCreateSignatureEnvironmentProfile(Element profileElem) { CreateSignatureLocation createSignatureLocation = parseCreateSignatureLocation(profileElem); List supplements = parseSupplements(profileElem); return factory.createCreateSignatureEnvironmentProfile( createSignatureLocation, supplements); } /** * Parse a CreateSignatureLocation DOM element contained in * a CreateSignatureEnvironmentProfile. * * @param profileElem The CreateSignatureEnvironmentProfile DOM * element containing the CreateSignatureLocation. * @return The CreateSignatureLocation API object containing * the data from the CreateSignatureLocation DOM element. */ private CreateSignatureLocation parseCreateSignatureLocation(Element profileElem) { Element locationElem = (Element) XPathUtils.selectSingleNode( profileElem, CREATE_SIGNATURE_LOCATION_XPATH); String xPathExpression = DOMUtils.getText(locationElem); Map namespaceDeclarations = DOMUtils.getNamespaceDeclarations(locationElem); String indexStr = locationElem.getAttribute("Index"); int index = Integer.parseInt(indexStr); return factory.createCreateSignatureLocation( xPathExpression, index, namespaceDeclarations); } /** * Parse all Supplement DOM elements contained in a given * parent DOM element. * * @param supplementsParentElem The DOM element being the parent of the * Supplements. * @return A List of Supplement API objects * containing the data from the Supplement DOM elements. */ private List parseSupplements(Element supplementsParentElem) { List supplements = new ArrayList(); NodeIterator supplementElems = XPathUtils.selectNodeIterator(supplementsParentElem, SUPPLEMENT_XPATH); Element supplementElem; while ((supplementElem = (Element) supplementElems.nextNode()) != null) { XMLDataObjectAssociation supplement = RequestParserUtils.parseXMLDataObjectAssociation(supplementElem); supplements.add(supplement); } return supplements; } /** * Parse a SupplementProfile DOM element. * * @param profileElem The SupplementProfile DOM element to parse. * @return The SupplementProfile API object containing the * data from the SupplementProfile DOM element. */ public SupplementProfile parseSupplementProfile(Element profileElem) { XMLDataObjectAssociation supplementProfile = RequestParserUtils.parseXMLDataObjectAssociation(profileElem); return factory.createSupplementProfile(supplementProfile); } /** * Parse a VerifyTransformsInfoProfile DOM element. * * @param profileElem The VerifyTransformsInfoProfile DOM * element to parse. * @return A VerifyTransformsInfoProfile API object containing * the information from the VerifyTransformsInfoProfile DOM * element. * @throws MOAApplicationException An error occurred parsing the * VerifyTransformsInfoProfile. */ public VerifyTransformsInfoProfile parseVerifyTransformsInfoProfile(Element profileElem) throws MOAApplicationException { Element transformsElem = (Element) XPathUtils.selectSingleNode( profileElem, VERIFY_TRANSFORMS_XPATH); List transforms = null; NodeIterator paramElems = XPathUtils.selectNodeIterator(profileElem, TRANSFORM_PARAMETER_XPATH); Element paramElem; List transformParameters = new ArrayList(); // parse the dsig:Transforms if (transformsElem != null) { TransformParser transformsParser = new TransformParser(); transforms = transformsParser.parseTransforms(transformsElem); } // parse the TransformParameter elements while ((paramElem = (Element) paramElems.nextNode()) != null) { transformParameters.add(parseTransformParameter(paramElem)); } return factory.createVerifyTransformsInfoProfile( transforms, transformParameters); } /** * Parse a TransformParameter DOM element. * * @param paramElem The TransformParameter DOM element to * parse. * @return The TransformParameter API object containing the * information from the TransformParameter DOM element. * @throws MOAApplicationException An error occurred parsing the * TransformParameter DOM element. */ private TransformParameter parseTransformParameter(Element paramElem) throws MOAApplicationException { String uri = paramElem.getAttribute("URI"); Element contentElem = (Element) XPathUtils.selectSingleNode( paramElem, TRANSFORM_PARAMETER_CONTENT_XPATH); if (contentElem == null) { return factory.createTransformParameter(uri); } else if ("Base64Content".equals(contentElem.getLocalName())) { String base64Str = DOMUtils.getText(contentElem); InputStream binaryContent = Base64Utils.decodeToStream(base64Str, true); return factory.createTransformParameter(uri, binaryContent); } else { // "Hash".equals(contentElem.getLocalName()) String digestMethodStr = XPathUtils.getElementValue(contentElem, DIGEST_METHOD_XPATH, ""); String digestValueStr = XPathUtils.getElementValue(contentElem, DIGEST_VALUE_XPATH, ""); byte[] digestValue = null; try { digestValue = Base64Utils.decode(digestValueStr, true); } catch (IOException e) { throw new MOAApplicationException("2270", null); } return factory.createTransformParameter( uri, digestMethodStr, digestValue); } } }