/*
* 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 final 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 {
final List transforms = new ArrayList();
final 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 {
final 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) {
final Element inclusiveNamespacesElem =
(Element) XPathUtils.selectSingleNode(
transformElem,
INCLUSIVE_NAMESPACES_XPATH);
final List inclusiveNamespaces = new ArrayList();
if (inclusiveNamespacesElem != null) {
final 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 {
final 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 {
final List filters = new ArrayList();
final NodeIterator iter =
XPathUtils.selectNodeIterator(transformElem, XPATH2_XPATH);
Element filterElem;
while ((filterElem = (Element) iter.nextNode()) != null) {
final 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 {
final Element xsltElem =
(Element) XPathUtils.selectSingleNode(transformElem, XSLT_ELEMENT_XPATH);
if (xsltElem == null) {
throw new MOAApplicationException("2215", null);
}
return factory.createXSLTTransform(xsltElem);
}
}