aboutsummaryrefslogtreecommitdiff
path: root/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java')
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java217
1 files changed, 217 insertions, 0 deletions
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java
new file mode 100644
index 0000000..1c5d26a
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java
@@ -0,0 +1,217 @@
+/*
+ * 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.server.iaik.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
+
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.spss.util.NodeListToNodeSetDataAdapter;
+import at.gv.egovernment.moa.util.NodeListAdapter;
+import at.gv.egovernment.moa.util.StreamUtils;
+import at.gv.egovernment.moa.util.XPathException;
+import at.gv.egovernment.moa.util.XPathUtils;
+import iaik.server.modules.xml.XSLTTransformation;
+import iaik.xml.crypto.dsig.XMLSignatureFactory;
+
+/**
+ * A <code>Transformation</code> containing an XSLT transformation.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XSLTTransformationImpl extends TransformationImpl implements XSLTTransformation {
+
+ /** The XSLT stylesheet. */
+ private Element styleSheetElement;
+ /**
+ * The hash code of the canonicalized stylesheet. If calculated, this value
+ * should be != 0.
+ */
+ private int hashCode;
+
+ /**
+ * Create a new <code>XSLTTransformationImpl</code> object.
+ *
+ * @param styleSheetElement
+ * The XSLT stylesheet element.
+ */
+ public XSLTTransformationImpl(Element styleSheetElement) {
+ setAlgorithmURI(XSLTTransformation.XSLT);
+ setStyleSheetElement(styleSheetElement);
+ }
+
+ /**
+ * Set the XSLT stylesheet element.
+ *
+ * @param styleSheetElement
+ * The XSLT stylesheet element to set.
+ */
+ protected void setStyleSheetElement(Element styleSheetElement) {
+ this.styleSheetElement = styleSheetElement;
+ this.hashCode = 0;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XSLTTransformation#getStylesheetElement()
+ */
+ public Element getStylesheetElement() {
+ return styleSheetElement;
+ }
+
+ /**
+ * Compare this <code>XSLTTransformation</code> to another.
+ *
+ * @param other
+ * The object to compare this <code>XSLTTransformation</code> to.
+ * @return <code>true</code>, if <code>other</code> is an
+ * <code>XSLTTransformation</code> and if the canonicalized
+ * representations of the stylesheets contained in <code>this</code>
+ * and <code>other</code> match. Otherwise, <code>false</code> is
+ * returned.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof XSLTTransformation) {
+ XSLTTransformation xslt = (XSLTTransformation) other;
+
+ return compareElements(getStylesheetElement(), xslt.getStylesheetElement());
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ if (hashCode == 0) {
+ hashCode = calculateHashCode(getStylesheetElement());
+ }
+ return hashCode;
+ }
+
+ /**
+ * Calculate the hash code for a DOM element by canonicalizing it.
+ *
+ * @param element
+ * The DOM element for which the hash code is to be calculated.
+ * @return int The hash code, or <code>0</code>, if it could not be
+ * calculated.
+ */
+ private static int calculateHashCode(Element element) {
+ try {
+ InputStream is = canonicalize(element);
+ byte[] buf = new byte[256];
+ int hashCode = 1;
+ int length;
+ int i;
+
+ while ((length = is.read(buf)) > 0) {
+ for (i = 0; i < length; i++) {
+ hashCode += buf[i] * 31 + i;
+ }
+ }
+ is.close();
+ return hashCode;
+ } catch (IOException e) {
+ return 0;
+ } catch (NoSuchAlgorithmException e) {
+ return 0;
+ } catch (InvalidAlgorithmParameterException e) {
+ return 0;
+ } catch (TransformException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Compare two DOM elements by canonicalizing their contents and comparing
+ * the resulting byte stream.
+ *
+ * @param elem1
+ * The 1st element to compare.
+ * @param elem2
+ * The 2nd element to compare.
+ * @return boolean <code>true</code>, if the elements are considered equal
+ * after canonicalization. Otherwise <code>false</code> is returned.
+ */
+ private static boolean compareElements(Element elem1, Element elem2) {
+ try {
+ InputStream is1 = canonicalize(elem1);
+ InputStream is2 = canonicalize(elem2);
+ return StreamUtils.compareStreams(is1, is2);
+ } catch (IOException e) {
+ return false;
+ } catch (NoSuchAlgorithmException e) {
+ return false;
+ } catch (InvalidAlgorithmParameterException e) {
+ return false;
+ } catch (TransformException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Canonicalize a DOM element.
+ *
+ * @param element The element to canonicalize.
+ * @return InputStream A stream with the canonicalized data.
+ * @throws InvalidAlgorithmParameterException
+ * @throws IOException
+ * @throws TransformException
+ * @throws AlgorithmException An error occurred canonicalizing the element.
+ */
+ private static InputStream canonicalize(Element element)
+ throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException, TransformException {
+ CanonicalizationMethod canonicalizationMethod = XMLSignatureFactory.getInstance().newCanonicalizationMethod(
+ CanonicalizationMethod.EXCLUSIVE, new ExcC14NParameterSpec());
+
+ //CanonicalizationAlgorithm c14n =
+ // new CanonicalizationAlgorithmImplExclusiveCanonicalXML();
+ NodeList nodeList;
+
+ try {
+ nodeList = XPathUtils.selectNodeList(element, XPathUtils.ALL_NODES_XPATH);
+ } catch (XPathException e) {
+ nodeList = new NodeListAdapter(Collections.EMPTY_LIST);
+ }
+ //c14n.setInput(nodeList);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ canonicalizationMethod.transform(new NodeListToNodeSetDataAdapter(nodeList), null, baos);
+ baos.close();
+ return new ByteArrayInputStream(baos.toByteArray());
+ }
+
+}