KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > xml > crypto > dsig > TransformService


1 /*
2  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3  */

4 /*
5  * $Id: TransformService.java,v 1.6.4.1 2005/09/15 12:42:11 mullan Exp $
6  */

7 package javax.xml.crypto.dsig;
8
9 import java.security.InvalidAlgorithmParameterException JavaDoc;
10 import java.security.NoSuchAlgorithmException JavaDoc;
11 import java.security.NoSuchProviderException JavaDoc;
12 import java.security.Provider JavaDoc;
13 import java.security.Provider.Service;
14 import java.security.Security JavaDoc;
15 import java.util.*;
16 import javax.xml.crypto.MarshalException;
17 import javax.xml.crypto.XMLStructure;
18 import javax.xml.crypto.XMLCryptoContext;
19 import javax.xml.crypto.dsig.spec.TransformParameterSpec;
20
21 import sun.security.jca.*;
22 import sun.security.jca.GetInstance.Instance;
23
24 /**
25  * A Service Provider Interface for transform and canonicalization algorithms.
26  *
27  * <p>Each instance of <code>TransformService</code> supports a specific
28  * transform or canonicalization algorithm and XML mechanism type. To create a
29  * <code>TransformService</code>, call one of the static
30  * {@link #getInstance getInstance} methods, passing in the algorithm URI and
31  * XML mechanism type desired, for example:
32  *
33  * <blockquote><code>
34  * TransformService ts = TransformService.getInstance(Transform.XPATH2, "DOM");
35  * </code></blockquote>
36  *
37  * <p><code>TransformService</code> implementations are registered and loaded
38  * using the {@link java.security.Provider} mechanism. Each
39  * <code>TransformService</code> service provider implementation should include
40  * a <code>MechanismType</code> service attribute that identifies the XML
41  * mechanism type that it supports. If the attribute is not specified,
42  * "DOM" is assumed. For example, a service provider that supports the
43  * XPath Filter 2 Transform and DOM mechanism would be specified in the
44  * <code>Provider</code> subclass as:
45  * <pre>
46  * put("TransformService." + Transform.XPATH2,
47  * "org.example.XPath2TransformService");
48  * put("TransformService." + Transform.XPATH2 + " MechanismType", "DOM");
49  * </pre>
50  * <code>TransformService</code> implementations that support the DOM
51  * mechanism type must abide by the DOM interoperability requirements defined
52  * in the
53  * <a HREF="../../../../../technotes/guides/security/xmldsig/overview.html#DOM Mechanism Requirements">
54  * DOM Mechanism Requirements</a> section of the API overview. See the
55  * <a HREF="../../../../../technotes/guides/security/xmldsig/overview.html#Service Provider">
56  * Service Providers</a> section of the API overview for a list of standard
57  * mechanism types.
58  * <p>
59  * Once a <code>TransformService</code> has been created, it can be used
60  * to process <code>Transform</code> or <code>CanonicalizationMethod</code>
61  * objects. If the <code>Transform</code> or <code>CanonicalizationMethod</code>
62  * exists in XML form (for example, when validating an existing
63  * <code>XMLSignature</code>), the {@link #init(XMLStructure, XMLCryptoContext)}
64  * method must be first called to initialize the transform and provide document
65  * context (even if there are no parameters). Alternatively, if the
66  * <code>Transform</code> or <code>CanonicalizationMethod</code> is being
67  * created from scratch, the {@link #init(TransformParameterSpec)} method
68  * is called to initialize the transform with parameters and the
69  * {@link #marshalParams marshalParams} method is called to marshal the
70  * parameters to XML and provide the transform with document context. Finally,
71  * the {@link #transform transform} method is called to perform the
72  * transformation.
73  * <p>
74  * <b>Concurrent Access</b>
75  * <p>The static methods of this class are guaranteed to be thread-safe.
76  * Multiple threads may concurrently invoke the static methods defined in this
77  * class with no ill effects.
78  *
79  * <p>However, this is not true for the non-static methods defined by this
80  * class. Unless otherwise documented by a specific provider, threads that
81  * need to access a single <code>TransformService</code> instance
82  * concurrently should synchronize amongst themselves and provide the
83  * necessary locking. Multiple threads each manipulating a different
84  * <code>TransformService</code> instance need not synchronize.
85  *
86  * @author Sean Mullan
87  * @author JSR 105 Expert Group
88  * @since 1.6
89  */

90 public abstract class TransformService implements Transform {
91
92     private String JavaDoc algorithm;
93     private String JavaDoc mechanism;
94     private Provider JavaDoc provider;
95
96     /**
97      * Default constructor, for invocation by subclasses.
98      */

99     protected TransformService() {}
100
101     /**
102      * Returns a <code>TransformService</code> that supports the specified
103      * algorithm URI (ex: {@link Transform#XPATH2}) and mechanism type
104      * (ex: DOM).
105      *
106      * <p>This method uses the standard JCA provider lookup mechanism to
107      * locate and instantiate a <code>TransformService</code> implementation
108      * of the desired algorithm and <code>MechanismType</code> service
109      * attribute. It traverses the list of registered security
110      * <code>Provider</code>s, starting with the most preferred
111      * <code>Provider</code>. A new <code>TransformService</code> object
112      * from the first <code>Provider</code> that supports the specified
113      * algorithm and mechanism type is returned.
114      *
115      * <p> Note that the list of registered providers may be retrieved via
116      * the {@link Security#getProviders() Security.getProviders()} method.
117      *
118      * @param algorithm the URI of the algorithm
119      * @param mechanismType the type of the XML processing mechanism and
120      * representation
121      * @return a new <code>TransformService</code>
122      * @throws NullPointerException if <code>algorithm</code> or
123      * <code>mechanismType</code> is <code>null</code>
124      * @throws NoSuchAlgorithmException if no <code>Provider</code> supports a
125      * <code>TransformService</code> implementation for the specified
126      * algorithm and mechanism type
127      * @see Provider
128      */

129     public static TransformService getInstance
130     (String JavaDoc algorithm, String JavaDoc mechanismType)
131     throws NoSuchAlgorithmException JavaDoc {
132     if (mechanismType == null || algorithm == null) {
133         throw new NullPointerException JavaDoc();
134     }
135     boolean dom = false;
136     if (mechanismType.equals("DOM")) {
137         dom = true;
138     }
139         List services = GetInstance.getServices("TransformService", algorithm);
140         for (Iterator t = services.iterator(); t.hasNext(); ) {
141             Service s = (Service)t.next();
142         String JavaDoc value = s.getAttribute("MechanismType");
143         if ((value == null && dom) ||
144         (value != null && value.equals(mechanismType))) {
145                 Instance instance = GetInstance.getInstance(s, null);
146             TransformService ts = (TransformService) instance.impl;
147             ts.algorithm = algorithm;
148             ts.mechanism = mechanismType;
149             ts.provider = instance.provider;
150             return ts;
151         }
152         }
153         throw new NoSuchAlgorithmException JavaDoc
154             (algorithm + " algorithm and " + mechanismType
155          + " mechanism not available");
156     }
157
158     /**
159      * Returns a <code>TransformService</code> that supports the specified
160      * algorithm URI (ex: {@link Transform#XPATH2}) and mechanism type
161      * (ex: DOM) as supplied by the specified provider. Note that the specified
162      * <code>Provider</code> object does not have to be registered in the
163      * provider list.
164      *
165      * @param algorithm the URI of the algorithm
166      * @param mechanismType the type of the XML processing mechanism and
167      * representation
168      * @param provider the <code>Provider</code> object
169      * @return a new <code>TransformService</code>
170      * @throws NullPointerException if <code>provider</code>,
171      * <code>algorithm</code>, or <code>mechanismType</code> is
172      * <code>null</code>
173      * @throws NoSuchAlgorithmException if a <code>TransformService</code>
174      * implementation for the specified algorithm and mechanism type is not
175      * available from the specified <code>Provider</code> object
176      * @see Provider
177      */

178     public static TransformService getInstance
179     (String JavaDoc algorithm, String JavaDoc mechanismType, Provider JavaDoc provider)
180     throws NoSuchAlgorithmException JavaDoc {
181     if (mechanismType == null || algorithm == null || provider == null) {
182         throw new NullPointerException JavaDoc();
183     }
184
185     boolean dom = false;
186     if (mechanismType.equals("DOM")) {
187         dom = true;
188     }
189         Service s = GetInstance.getService
190             ("TransformService", algorithm, provider);
191         String JavaDoc value = s.getAttribute("MechanismType");
192         if ((value == null && dom) ||
193         (value != null && value.equals(mechanismType))) {
194             Instance instance = GetInstance.getInstance(s, null);
195             TransformService ts = (TransformService) instance.impl;
196             ts.algorithm = algorithm;
197             ts.mechanism = mechanismType;
198             ts.provider = instance.provider;
199             return ts;
200     }
201         throw new NoSuchAlgorithmException JavaDoc
202             (algorithm + " algorithm and " + mechanismType
203          + " mechanism not available");
204     }
205
206     /**
207      * Returns a <code>TransformService</code> that supports the specified
208      * algorithm URI (ex: {@link Transform#XPATH2}) and mechanism type
209      * (ex: DOM) as supplied by the specified provider. The specified provider
210      * must be registered in the security provider list.
211      *
212      * <p>Note that the list of registered providers may be retrieved via
213      * the {@link Security#getProviders() Security.getProviders()} method.
214      *
215      * @param algorithm the URI of the algorithm
216      * @param mechanismType the type of the XML processing mechanism and
217      * representation
218      * @param provider the string name of the provider
219      * @return a new <code>TransformService</code>
220      * @throws NoSuchProviderException if the specified provider is not
221      * registered in the security provider list
222      * @throws NullPointerException if <code>provider</code>,
223      * <code>mechanismType</code>, or <code>algorithm</code> is
224      * <code>null</code>
225      * @throws NoSuchAlgorithmException if a <code>TransformService</code>
226      * implementation for the specified algorithm and mechanism type is not
227      * available from the specified provider
228      * @see Provider
229      */

230     public static TransformService getInstance
231     (String JavaDoc algorithm, String JavaDoc mechanismType, String JavaDoc provider)
232     throws NoSuchAlgorithmException JavaDoc, NoSuchProviderException JavaDoc {
233     if (mechanismType == null || algorithm == null || provider == null) {
234         throw new NullPointerException JavaDoc();
235     } else if (provider.length() == 0) {
236         throw new NoSuchProviderException JavaDoc();
237     }
238     boolean dom = false;
239     if (mechanismType.equals("DOM")) {
240         dom = true;
241     }
242         Service s = GetInstance.getService
243             ("TransformService", algorithm, provider);
244         String JavaDoc value = s.getAttribute("MechanismType");
245         if ((value == null && dom) ||
246         (value != null && value.equals(mechanismType))) {
247             Instance instance = GetInstance.getInstance(s, null);
248             TransformService ts = (TransformService) instance.impl;
249             ts.algorithm = algorithm;
250             ts.mechanism = mechanismType;
251             ts.provider = instance.provider;
252             return ts;
253     }
254         throw new NoSuchAlgorithmException JavaDoc
255             (algorithm + " algorithm and " + mechanismType
256          + " mechanism not available");
257     }
258
259     private static class MechanismMapEntry implements Map.Entry {
260     private final String JavaDoc mechanism;
261     private final String JavaDoc algorithm;
262     private final String JavaDoc key;
263     MechanismMapEntry(String JavaDoc algorithm, String JavaDoc mechanism) {
264         this.algorithm = algorithm;
265         this.mechanism = mechanism;
266         this.key = "TransformService." + algorithm + " MechanismType";
267     }
268     public boolean equals(Object JavaDoc o) {
269         if (!(o instanceof Map.Entry)) {
270         return false;
271         }
272         Map.Entry e = (Map.Entry) o;
273         return (getKey()==null ?
274             e.getKey()==null : getKey().equals(e.getKey())) &&
275                (getValue()==null ?
276                 e.getValue()==null : getValue().equals(e.getValue()));
277     }
278     public Object JavaDoc getKey() {
279         return key;
280     }
281     public Object JavaDoc getValue() {
282         return mechanism;
283     }
284     public Object JavaDoc setValue(Object JavaDoc value) {
285         throw new UnsupportedOperationException JavaDoc();
286     }
287     public int hashCode() {
288         return (getKey()==null ? 0 : getKey().hashCode()) ^
289                (getValue()==null ? 0 : getValue().hashCode());
290     }
291     }
292
293     /**
294      * Returns the mechanism type supported by this <code>TransformService</code>.
295      *
296      * @return the mechanism type
297      */

298     public final String JavaDoc getMechanismType() {
299     return mechanism;
300     }
301
302     /**
303      * Returns the URI of the algorithm supported by this
304      * <code>TransformService</code>.
305      *
306      * @return the algorithm URI
307      */

308     public final String JavaDoc getAlgorithm() {
309     return algorithm;
310     }
311
312     /**
313      * Returns the provider of this <code>TransformService</code>.
314      *
315      * @return the provider
316      */

317     public final Provider JavaDoc getProvider() {
318     return provider;
319     }
320
321     /**
322      * Initializes this <code>TransformService</code> with the specified
323      * parameters.
324      *
325      * <p>If the parameters exist in XML form, the
326      * {@link #init(XMLStructure, XMLCryptoContext)} method should be used to
327      * initialize the <code>TransformService</code>.
328      *
329      * @param params the algorithm parameters (may be <code>null</code> if
330      * not required or optional)
331      * @throws InvalidAlgorithmParameterException if the specified parameters
332      * are invalid for this algorithm
333      */

334     public abstract void init(TransformParameterSpec params)
335     throws InvalidAlgorithmParameterException JavaDoc;
336
337     /**
338      * Marshals the algorithm-specific parameters. If there are no parameters
339      * to be marshalled, this method returns without throwing an exception.
340      *
341      * @param parent a mechanism-specific structure containing the parent
342      * node that the marshalled parameters should be appended to
343      * @param context the <code>XMLCryptoContext</code> containing
344      * additional context (may be <code>null</code> if not applicable)
345      * @throws ClassCastException if the type of <code>parent</code> or
346      * <code>context</code> is not compatible with this
347      * <code>TransformService</code>
348      * @throws NullPointerException if <code>parent</code> is <code>null</code>
349      * @throws MarshalException if the parameters cannot be marshalled
350      */

351     public abstract void marshalParams
352     (XMLStructure parent, XMLCryptoContext context)
353     throws MarshalException;
354
355     /**
356      * Initializes this <code>TransformService</code> with the specified
357      * parameters and document context.
358      *
359      * @param parent a mechanism-specific structure containing the parent
360      * structure
361      * @param context the <code>XMLCryptoContext</code> containing
362      * additional context (may be <code>null</code> if not applicable)
363      * @throws ClassCastException if the type of <code>parent</code> or
364      * <code>context</code> is not compatible with this
365      * <code>TransformService</code>
366      * @throws NullPointerException if <code>parent</code> is <code>null</code>
367      * @throws InvalidAlgorithmParameterException if the specified parameters
368      * are invalid for this algorithm
369      */

370     public abstract void init(XMLStructure parent, XMLCryptoContext context)
371     throws InvalidAlgorithmParameterException JavaDoc;
372 }
373
Popular Tags