blob: 17fe64676e57f9b08305410ba8dbd8c67b557f41 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5
6/*
7 * Copyright 1999-2004 The Apache Software Foundation.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 */
22package com.sun.org.apache.xml.internal.security.transforms.implementations;
23
24
25
26import java.io.ByteArrayInputStream;
27import java.io.ByteArrayOutputStream;
28import java.io.IOException;
29import java.io.OutputStream;
30
31import javax.xml.XMLConstants;
32import javax.xml.transform.Source;
33import javax.xml.transform.Transformer;
34import javax.xml.transform.TransformerConfigurationException;
35import javax.xml.transform.TransformerException;
36import javax.xml.transform.TransformerFactory;
37import javax.xml.transform.dom.DOMSource;
38import javax.xml.transform.stream.StreamResult;
39import javax.xml.transform.stream.StreamSource;
40
41import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
42import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
43import com.sun.org.apache.xml.internal.security.transforms.TransformSpi;
44import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
45import com.sun.org.apache.xml.internal.security.transforms.Transforms;
46import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
47import org.w3c.dom.Element;
48
49
50/**
51 * Class TransformXSLT
52 *
53 * Implements the <CODE>http://www.w3.org/TR/1999/REC-xslt-19991116</CODE>
54 * transform.
55 *
56 * @author Christian Geuer-Pollmann
57 */
58public class TransformXSLT extends TransformSpi {
59
60 /** Field implementedTransformURI */
61 public static final String implementedTransformURI =
62 Transforms.TRANSFORM_XSLT;
63 //J-
64 static final String XSLTSpecNS = "http://www.w3.org/1999/XSL/Transform";
65 static final String defaultXSLTSpecNSprefix = "xslt";
66 static final String XSLTSTYLESHEET = "stylesheet";
67
68
69 /**
70 * Method engineGetURI
71 *
72 * @inheritDoc
73 */
74 protected String engineGetURI() {
75 return implementedTransformURI;
76 }
77
78 /**
79 * Method enginePerformTransform
80 *
81 * @param input the input for this transform
82 * @return the result of this Transform
83 * @throws IOException
84 * @throws TransformationException
85 */
86 protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input)
87 throws IOException,
88 TransformationException {
89 return enginePerformTransform(input,null);
90 }
91 protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input,OutputStream baos)
92 throws IOException,
93 TransformationException {
94 try {
95 Element transformElement = this._transformObject.getElement();
96
97 Element _xsltElement =
98 XMLUtils.selectNode(transformElement.getFirstChild(),
99 XSLTSpecNS,"stylesheet", 0);
100
101 if (_xsltElement == null) {
102 Object exArgs[] = { "xslt:stylesheet", "Transform" };
103
104 throw new TransformationException("xml.WrongContent", exArgs);
105 }
106
107 TransformerFactory tFactory = TransformerFactory.newInstance();
108 // Process XSLT stylesheets in a secure manner
109 tFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
110
111 /*
112 * This transform requires an octet stream as input. If the actual
113 * input is an XPath node-set, then the signature application should
114 * attempt to convert it to octets (apply Canonical XML]) as described
115 * in the Reference Processing Model (section 4.3.3.2).
116 */
117 Source xmlSource =
118 new StreamSource(new ByteArrayInputStream(input.getBytes()));
119 Source stylesheet;
120
121 /*
122 * This complicated transformation of the stylesheet itself is necessary
123 * because of the need to get the pure style sheet. If we simply say
124 * Source stylesheet = new DOMSource(this._xsltElement);
125 * whereby this._xsltElement is not the rootElement of the Document,
126 * this causes problems;
127 * so we convert the stylesheet to byte[] and use this as input stream
128 */
129 {
130 ByteArrayOutputStream os = new ByteArrayOutputStream();
131 Transformer transformer = tFactory.newTransformer();
132 DOMSource source = new DOMSource(_xsltElement);
133 StreamResult result = new StreamResult(os);
134
135 transformer.transform(source, result);
136
137 stylesheet =
138 new StreamSource(new ByteArrayInputStream(os.toByteArray()));
139 }
140
141 Transformer transformer = tFactory.newTransformer(stylesheet);
142 if (baos==null) {
143 ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
144 StreamResult outputTarget = new StreamResult(baos1);
145 transformer.transform(xmlSource, outputTarget);
146 return new XMLSignatureInput(baos1.toByteArray());
147
148 }
149 StreamResult outputTarget = new StreamResult(baos);
150
151 transformer.transform(xmlSource, outputTarget);
152 XMLSignatureInput output=new XMLSignatureInput((byte[])null);
153 output.setOutputStream(baos);
154 return output;
155 } catch (XMLSecurityException ex) {
156 Object exArgs[] = { ex.getMessage() };
157
158 throw new TransformationException("generic.EmptyMessage", exArgs, ex);
159 } catch (TransformerConfigurationException ex) {
160 Object exArgs[] = { ex.getMessage() };
161
162 throw new TransformationException("generic.EmptyMessage", exArgs, ex);
163 } catch (TransformerException ex) {
164 Object exArgs[] = { ex.getMessage() };
165
166 throw new TransformationException("generic.EmptyMessage", exArgs, ex);
167 }
168 }
169}