KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > transforms > Transform


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package com.sun.org.apache.xml.internal.security.transforms;
18
19
20
21 import java.io.IOException JavaDoc;
22 import java.io.OutputStream JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.security.AccessController JavaDoc;
25 import java.security.PrivilegedAction JavaDoc;
26
27 import javax.xml.parsers.ParserConfigurationException JavaDoc;
28
29 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
30 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
31 import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
32 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
33 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
34 import com.sun.org.apache.xml.internal.security.utils.Constants;
35 import com.sun.org.apache.xml.internal.security.utils.HelperNodeList;
36 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
37 import org.w3c.dom.Document JavaDoc;
38 import org.w3c.dom.Element JavaDoc;
39 import org.w3c.dom.NodeList JavaDoc;
40 import org.xml.sax.SAXException JavaDoc;
41
42
43 /**
44  * Implements the behaviour of the <code>ds:Transform</code> element.
45  *
46  * This <code>Transform</code>(Factory) class role as the Factory and Proxy of
47  * implemanting class that have the functionality of <a
48  * HREF=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>a Transform
49  * algorithm</a>.
50  * Implements the Factory and Proxy pattern for ds:Transform algorithms.
51  *
52  * @author Christian Geuer-Pollmann
53  * @see Transforms
54  * @see TransformSpi
55  *
56  */

57 public final class Transform extends SignatureElementProxy {
58
59    /** {@link java.util.logging} logging facility */
60     static java.util.logging.Logger JavaDoc log =
61         java.util.logging.Logger.getLogger(Transform.class.getName());
62
63    /** Field _alreadyInitialized */
64    static boolean _alreadyInitialized = false;
65
66    /** All available Transform classes are registered here */
67    static HashMap JavaDoc _transformHash = null;
68
69    /** Field transformSpi */
70    protected TransformSpi transformSpi = null;
71
72    /**
73     * Constructs {@link Transform}
74     *
75     * @param doc the {@link Document} in which <code>Transform</code> will be placed
76     * @param algorithmURI URI representation of
77     * <code>Transform algorithm</code> will be specified as parameter of
78     * {@link #getInstance(Document, String)}, when generate. </br>
79     * @param contextNodes the child node list of <code>Transform</code> element
80     * @throws InvalidTransformException
81     */

82    public Transform(Document JavaDoc doc, String JavaDoc algorithmURI, NodeList contextNodes)
83            throws InvalidTransformException {
84
85       super(doc);
86
87       try {
88          this._constructionElement.setAttributeNS(null, Constants._ATT_ALGORITHM,
89                                                 algorithmURI);
90
91          Class JavaDoc implementingClass =
92             Transform.getImplementingClass(algorithmURI);
93          
94          if(implementingClass == null) {
95              Object JavaDoc exArgs[] = { algorithmURI };
96
97              throw new InvalidTransformException(
98                 "signature.Transform.UnknownTransform", exArgs);
99          }
100          if (true) {
101             if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Create URI \"" + algorithmURI + "\" class \""
102                    + implementingClass + "\"");
103             if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "The NodeList is " + contextNodes);
104          }
105
106          // create the custom Transform object
107
this.transformSpi =
108             (TransformSpi) implementingClass.newInstance();
109
110          this.transformSpi.setTransform(this);
111
112          // give it to the current document
113
if (contextNodes != null) {
114             /*
115             while (contextNodes.getLength() > 0) {
116                this._constructionElement.appendChild(contextNodes.item(0));
117             }
118             */

119
120             for (int i = 0; i < contextNodes.getLength(); i++) {
121                this._constructionElement.appendChild(contextNodes.item(i).cloneNode(true));
122             }
123
124          }
125       } catch (IllegalAccessException JavaDoc ex) {
126          Object JavaDoc exArgs[] = { algorithmURI };
127
128          throw new InvalidTransformException(
129             "signature.Transform.UnknownTransform", exArgs, ex);
130       } catch (InstantiationException JavaDoc ex) {
131          Object JavaDoc exArgs[] = { algorithmURI };
132
133          throw new InvalidTransformException(
134             "signature.Transform.UnknownTransform", exArgs, ex);
135       }
136    }
137
138    /**
139     * This constructor can only be called from the {@link Transforms} object, so
140     * it's protected.
141     *
142     * @param element <code>ds:Transform</code> element
143     * @param BaseURI the URI of the resource where the XML instance was stored
144     * @throws InvalidTransformException
145     * @throws TransformationException
146     * @throws XMLSecurityException
147     */

148    public Transform(Element JavaDoc element, String JavaDoc BaseURI)
149            throws InvalidTransformException, TransformationException,
150                   XMLSecurityException {
151
152       super(element, BaseURI);
153
154       // retrieve Algorithm Attribute from ds:Transform
155
String JavaDoc AlgorithmURI = element.getAttributeNS(null, Constants._ATT_ALGORITHM);
156
157       if ((AlgorithmURI == null) || (AlgorithmURI.length() == 0)) {
158          Object JavaDoc exArgs[] = { Constants._ATT_ALGORITHM,
159                              Constants._TAG_TRANSFORM };
160
161          throw new TransformationException("xml.WrongContent", exArgs);
162       }
163
164       try {
165          Class JavaDoc implementingClass = (Class JavaDoc) _transformHash.get(AlgorithmURI);
166          this.transformSpi =
167             (TransformSpi) implementingClass.newInstance();
168
169          this.transformSpi.setTransform(this);
170       } catch (IllegalAccessException JavaDoc e) {
171          Object JavaDoc exArgs[] = { AlgorithmURI };
172
173          throw new InvalidTransformException(
174             "signature.Transform.UnknownTransform", exArgs);
175       } catch (InstantiationException JavaDoc e) {
176          Object JavaDoc exArgs[] = { AlgorithmURI };
177
178          throw new InvalidTransformException(
179             "signature.Transform.UnknownTransform", exArgs);
180       } catch (NullPointerException JavaDoc e) {
181           Object JavaDoc exArgs[] = { AlgorithmURI };
182
183              throw new InvalidTransformException(
184                 "signature.Transform.UnknownTransform", exArgs);
185     }
186    }
187
188    /**
189     * Generates a Transform object that implements the specified <code>Transform algorithm</code> URI.
190     *
191     * @param algorithmURI <code>Transform algorithm</code> URI representation, such as specified in <a HREF=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>Transform algorithm </a>
192     * @param doc the proxy {@link Document}
193     * @return <code>{@link Transform}</code> object
194     * @throws InvalidTransformException
195     */

196    public static final Transform getInstance(
197            Document JavaDoc doc, String JavaDoc algorithmURI) throws InvalidTransformException {
198       return Transform.getInstance(doc, algorithmURI, (NodeList) null);
199    }
200
201    /**
202     * Generates a Transform object that implements the specified <code>Transform algorithm</code> URI.
203     *
204     * @param algorithmURI <code>Transform algorithm</code> URI representation, such as specified in <a HREF=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>Transform algorithm </a>
205     * @param contextChild the child element of <code>Transform</code> element
206     * @param doc the proxy {@link Document}
207     * @return <code>{@link Transform}</code> object
208     * @throws InvalidTransformException
209     */

210    public static final Transform getInstance(
211            Document JavaDoc doc, String JavaDoc algorithmURI, Element JavaDoc contextChild)
212               throws InvalidTransformException {
213
214       HelperNodeList contextNodes = new HelperNodeList();
215
216       contextNodes.appendChild(doc.createTextNode("\n"));
217       contextNodes.appendChild(contextChild);
218       contextNodes.appendChild(doc.createTextNode("\n"));
219
220       return Transform.getInstance(doc, algorithmURI, contextNodes);
221    }
222
223    /**
224     * Generates a Transform object that implements the specified <code>Transform algorithm</code> URI.
225     *
226     * @param algorithmURI <code>Transform algorithm</code> URI form, such as specified in <a HREF=http://www.w3.org/TR/xmldsig-core/#sec-TransformAlg>Transform algorithm </a>
227     * @param contextNodes the child node list of <code>Transform</code> element
228     * @param doc the proxy {@link Document}
229     * @return <code>{@link Transform}</code> object
230     * @throws InvalidTransformException
231     */

232    public static final Transform getInstance(
233            Document JavaDoc doc, String JavaDoc algorithmURI, NodeList contextNodes)
234               throws InvalidTransformException {
235       return new Transform(doc, algorithmURI, contextNodes);
236    }
237
238    /**
239     * Initalizes for this {@link Transform}
240     *
241     */

242    public static void init() {
243
244       if (!_alreadyInitialized) {
245          _transformHash = new HashMap JavaDoc(10);
246          _alreadyInitialized = true;
247       }
248    }
249
250    /**
251     * Registers implementing class of the Transform algorithm with algorithmURI
252     *
253     * @param algorithmURI algorithmURI URI representation of <code>Transform algorithm</code>
254     * will be specified as parameter of {@link #getInstance(Document, String)}, when generate. </br>
255     * @param implementingClass <code>implementingClass</code> the implementing class of {@link TransformSpi}
256     * @throws AlgorithmAlreadyRegisteredException if specified algorithmURI is already registered
257     */

258    public static void register(String JavaDoc algorithmURI, String JavaDoc implementingClass)
259            throws AlgorithmAlreadyRegisteredException {
260
261       {
262
263          // are we already registered?
264
Class JavaDoc registeredClass = Transform.getImplementingClass(algorithmURI);
265
266          if ((registeredClass != null) ) {
267             Object JavaDoc exArgs[] = { algorithmURI, registeredClass };
268
269             throw new AlgorithmAlreadyRegisteredException(
270                "algorithm.alreadyRegistered", exArgs);
271          }
272
273      ClassLoader JavaDoc cl = (ClassLoader JavaDoc) AccessController.doPrivileged(
274              new PrivilegedAction JavaDoc() {
275                  public Object JavaDoc run() {
276                      return Thread.currentThread().getContextClassLoader();
277                  }
278              });
279
280          try {
281          Transform._transformHash.put
282                  (algorithmURI, Class.forName(implementingClass, true, cl));
283      } catch (ClassNotFoundException JavaDoc e) {
284          // TODO Auto-generated catch block
285
e.printStackTrace();
286      }
287       }
288    }
289
290    /**
291     * Returns the URI representation of Transformation algorithm
292     *
293     * @return the URI representation of Transformation algorithm
294     */

295    public final String JavaDoc getURI() {
296       return this._constructionElement.getAttributeNS(null, Constants._ATT_ALGORITHM);
297    }
298
299    /**
300     * Transforms the input, and generats {@link XMLSignatureInput} as output.
301     * @param input input {@link XMLSignatureInput} which can supplied Octect Stream and NodeSet as Input of Transformation
302     *
303     * @return the {@link XMLSignatureInput} class as the result of transformation
304     * @throws CanonicalizationException
305     * @throws IOException
306     * @throws InvalidCanonicalizerException
307     * @throws TransformationException
308     */

309    public XMLSignatureInput performTransform(XMLSignatureInput input)
310            throws IOException JavaDoc, CanonicalizationException,
311                   InvalidCanonicalizerException, TransformationException {
312
313       XMLSignatureInput result = null;
314
315       try {
316          result = transformSpi.enginePerformTransform(input);
317       } catch (ParserConfigurationException JavaDoc ex) {
318          Object JavaDoc exArgs[] = { this.getURI(), "ParserConfigurationException" };
319
320          throw new CanonicalizationException(
321             "signature.Transform.ErrorDuringTransform", exArgs, ex);
322       } catch (SAXException JavaDoc ex) {
323          Object JavaDoc exArgs[] = { this.getURI(), "SAXException" };
324
325          throw new CanonicalizationException(
326             "signature.Transform.ErrorDuringTransform", exArgs, ex);
327       }
328
329       return result;
330    }
331    
332    /**
333     * Transforms the input, and generats {@link XMLSignatureInput} as output.
334     * @param input input {@link XMLSignatureInput} which can supplied Octect Stream and NodeSet as Input of Transformation
335     * @param os where to output the result of the last transformation
336     *
337     * @return the {@link XMLSignatureInput} class as the result of transformation
338     * @throws CanonicalizationException
339     * @throws IOException
340     * @throws InvalidCanonicalizerException
341     * @throws TransformationException
342     */

343    public XMLSignatureInput performTransform(XMLSignatureInput input, OutputStream JavaDoc os)
344    throws IOException JavaDoc, CanonicalizationException,
345           InvalidCanonicalizerException, TransformationException {
346
347         XMLSignatureInput result = null;
348
349         try {
350             result = transformSpi.enginePerformTransform(input,os);
351         } catch (ParserConfigurationException JavaDoc ex) {
352             Object JavaDoc exArgs[] = { this.getURI(), "ParserConfigurationException" };
353
354             throw new CanonicalizationException(
355                     "signature.Transform.ErrorDuringTransform", exArgs, ex);
356         } catch (SAXException JavaDoc ex) {
357             Object JavaDoc exArgs[] = { this.getURI(), "SAXException" };
358
359             throw new CanonicalizationException(
360                     "signature.Transform.ErrorDuringTransform", exArgs, ex);
361         }
362
363         return result;
364    }
365
366    /**
367     * Method getImplementingClass
368     *
369     * @param URI
370     * @return The name of the class implementing the URI.
371     */

372    private static Class JavaDoc getImplementingClass(String JavaDoc URI) {
373        return (Class JavaDoc)Transform._transformHash.get(URI);
374    }
375
376    
377    /** @inheritDoc */
378    public String JavaDoc getBaseLocalName() {
379       return Constants._TAG_TRANSFORM;
380    }
381 }
382
Popular Tags