/* * 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.util.ArrayList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; 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.common.Base64Transform; import at.gv.egovernment.moa.spss.api.common.CanonicalizationTransform; import at.gv.egovernment.moa.spss.api.common.EnvelopedSignatureTransform; import at.gv.egovernment.moa.spss.api.common.ExclusiveCanonicalizationTransform; import at.gv.egovernment.moa.spss.api.common.Transform; import at.gv.egovernment.moa.spss.api.common.XPathFilter; import at.gv.egovernment.moa.spss.api.common.XPathFilter2Transform; import at.gv.egovernment.moa.spss.api.common.XPathTransform; import at.gv.egovernment.moa.spss.api.common.XSLTTransform; 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 XMLDsig Transform DOM elements into their * MOA SPSS API representation. * * @author Patrick Peck * @version $Id$ */ public class TransformParser { // // XPath expressions for selecting information from the DOM tree // private static final String DSIG = Constants.DSIG_PREFIX + ":"; private static final String DSIG_FILTER2 = Constants.DSIG_FILTER2_PREFIX + ":"; private static final String XSLT = Constants.XSLT_PREFIX + ":"; private static final String EC = Constants.DSIG_EC_PREFIX + ":"; private static final String TRANSFORM_XPATH = DSIG + "Transform"; private static final String XPATH_XPATH = DSIG + "XPath"; private static final String XSLT_ELEMENT_XPATH = XSLT + "stylesheet"; private static final String XPATH2_XPATH = (DSIG_FILTER2 + "XPath[@Filter=\"intersect\"] | ") + (DSIG_FILTER2 + "XPath[@Filter=\"subtract\"] | ") + (DSIG_FILTER2 + "XPath[@Filter=\"union\"]"); private static final String INCLUSIVE_NAMESPACES_XPATH = EC + "InclusiveNamespaces"; /** * The SPSSFactory to use for creating new API objects. */ private SPSSFactory factory = SPSSFactory.getInstance(); /** * Parse an XMLDsig Transforms DOM element. * * @param transformsElem The Transforms DOM element to parse. * @return A List of Transform API objects * containing the data from the individual Transform DOM * elements. * @throws MOAApplicationException An error occurred parsing the * Transforms DOM element. */ public List parseTransforms(Element transformsElem) throws MOAApplicationException { List transforms = new ArrayList(); NodeIterator transformElems = XPathUtils.selectNodeIterator(transformsElem, TRANSFORM_XPATH); Element transformElem; Transform transform; while ((transformElem = (Element) transformElems.nextNode()) != null) { transform = parseTransform(transformElem); transforms.add(transform); } return transforms; } /** * Parse an XMLDsig Transform DOM element. * * @param transformElem Transform DOM element to parse. * @return The Transform API object containing the data * from the Transform DOM element. * @throws MOAApplicationException An error occurred parsing the * Transform DOM element. */ public Transform parseTransform(Element transformElem) throws MOAApplicationException { String algorithmUri = transformElem.getAttribute("Algorithm"); if (CanonicalizationTransform.CANONICAL_XML.equals(algorithmUri) || CanonicalizationTransform.CANONICAL_XML_WITH_COMMENTS.equals( algorithmUri)) { return factory.createCanonicalizationTransform(algorithmUri); } else if ( ExclusiveCanonicalizationTransform.EXCLUSIVE_CANONICAL_XML.equals( algorithmUri) || ExclusiveCanonicalizationTransform .EXCLUSIVE_CANONICAL_XML_WITH_COMMENTS .equals( algorithmUri)) { return parseExclusiveC14nTransform(algorithmUri, transformElem); } else if (Base64Transform.BASE64_DECODING.equals(algorithmUri)) { return factory.createBase64Transform(); } else if ( EnvelopedSignatureTransform.ENVELOPED_SIGNATURE.equals(algorithmUri)) { return factory.createEnvelopedSignatureTransform(); } else if (XPathTransform.XPATH.equals(algorithmUri)) { return parseXPathTransform(transformElem); } else if (XPathFilter2Transform.XPATH_FILTER2.equals(algorithmUri)) { return parseXPathFilter2Transform(transformElem); } else if (XSLTTransform.XSLT.equals(algorithmUri)) { return parseXSLTTransform(transformElem); } else { throw new MOAApplicationException("1108", new Object[] { algorithmUri }); } } /** * Parse an exclusive canonicalization type of transform. * * @param algorithmUri The algorithm URI of the canonicalization algorithm. * @param transformElem The Transform DOM element to parse. * @return An ExclusiveCanonicalizationTransform API object * containing the data from the transformElem. */ private Transform parseExclusiveC14nTransform( String algorithmUri, Element transformElem) { Element inclusiveNamespacesElem = (Element) XPathUtils.selectSingleNode( transformElem, INCLUSIVE_NAMESPACES_XPATH); List inclusiveNamespaces = new ArrayList(); if (inclusiveNamespacesElem != null) { StringTokenizer tokenizer = new StringTokenizer(inclusiveNamespacesElem.getAttribute("PrefixList")); while (tokenizer.hasMoreTokens()) { inclusiveNamespaces.add(tokenizer.nextToken()); } } return factory.createExclusiveCanonicalizationTransform( algorithmUri, inclusiveNamespaces); } /** * Parse an XPath type of Transform. * * @param transformElem The Transform DOM element to parse. * @return The Transform API object representation of the * Transform DOM element. * @throws MOAApplicationException An error occurred parsing the * Transform DOM element. */ private Transform parseXPathTransform(Element transformElem) throws MOAApplicationException { Element xPathElem = (Element) XPathUtils.selectSingleNode(transformElem, XPATH_XPATH); Map nsDecls; if (xPathElem == null) { throw new MOAApplicationException("2202", null); } nsDecls = DOMUtils.getNamespaceDeclarations(xPathElem); nsDecls.remove(""); return factory.createXPathTransform(DOMUtils.getText(xPathElem), nsDecls); } /** * Parse an XPathFilter2 type of Transform. * * @param transformElem The Transform DOM element to parse. * @return The Transform API object representation of the * Transform DOM element. * @throws MOAApplicationException An error occurred parsing the * Transform DOM element. */ private Transform parseXPathFilter2Transform(Element transformElem) throws MOAApplicationException { List filters = new ArrayList(); NodeIterator iter = XPathUtils.selectNodeIterator(transformElem, XPATH2_XPATH); Element filterElem; while ((filterElem = (Element) iter.nextNode()) != null) { String filterAttr = filterElem.getAttribute("Filter"); String filterType; String expression; Map nsDecls; if (filterAttr.equals("intersect")) { filterType = XPathFilter.INTERSECT_TYPE; } else if (filterAttr.equals("subtract")) { filterType = XPathFilter.SUBTRACT_TYPE; } else { filterType = XPathFilter.UNION_TYPE; } expression = DOMUtils.getText(filterElem); nsDecls = DOMUtils.getNamespaceDeclarations(filterElem); nsDecls.remove(""); filters.add(factory.createXPathFilter(filterType, expression, nsDecls)); } if (filters.size() == 0) { throw new MOAApplicationException("2216", null); } return factory.createXPathFilter2Transform(filters); } /** * Parse an XSLT type of Transform. * * @param transformElem The Transform DOM element to parse. * @return The Transform API object representation of the * Transform DOM element. * @throws MOAApplicationException An error occurred parsing the * Transform DOM element. */ private Transform parseXSLTTransform(Element transformElem) throws MOAApplicationException { Element xsltElem = (Element) XPathUtils.selectSingleNode(transformElem, XSLT_ELEMENT_XPATH); if (xsltElem == null) { throw new MOAApplicationException("2215", null); } return factory.createXSLTTransform(xsltElem); } }