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.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.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;
/**
* 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
.
* @throws MOAApplicationException An error occurred parsing the
* transformElem
.
*/
private Transform parseExclusiveC14nTransform(
String algorithmUri,
Element transformElem)
throws MOAApplicationException {
Element inclusiveNamespacesElem =
(Element) XPathUtils.selectSingleNode(
transformElem,
INCLUSIVE_NAMESPACES_XPATH);
if (inclusiveNamespacesElem == null) {
throw new MOAApplicationException("2217", null);
} else {
StringTokenizer tokenizer =
new StringTokenizer(inclusiveNamespacesElem.getAttribute("PrefixList"));
List inclusiveNamespaces = new ArrayList();
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);
}
}