KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > signature > XMLSignatureInput


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

18 package com.sun.org.apache.xml.internal.security.signature;
19
20
21
22 import java.io.ByteArrayInputStream JavaDoc;
23 import java.io.ByteArrayOutputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.io.UnsupportedEncodingException JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Set JavaDoc;
32
33 import javax.xml.parsers.DocumentBuilder JavaDoc;
34 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
35 import javax.xml.parsers.ParserConfigurationException JavaDoc;
36
37 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
38 import com.sun.org.apache.xml.internal.security.c14n.implementations.Canonicalizer20010315OmitComments;
39 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityRuntimeException;
40 import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
41 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
42 import org.w3c.dom.Document JavaDoc;
43 import org.w3c.dom.Node JavaDoc;
44 import org.xml.sax.SAXException JavaDoc;
45
46
47 /**
48  * Class XMLSignatureInput
49  *
50  * @author Christian Geuer-Pollmann
51  * $todo$ check whether an XMLSignatureInput can be _both_, octet stream _and_ node set?
52  */

53 public class XMLSignatureInput implements Cloneable JavaDoc {
54      static java.util.logging.Logger JavaDoc log =
55             java.util.logging.Logger.getLogger(XMLSignatureInput.class.getName());
56
57     /*
58      * The XMLSignature Input can be either:
59      * A byteArray like with/or without InputStream.
60      * Or a nodeSet like defined either:
61      * * as a collection of nodes
62      * * or as subnode excluding or not commets and excluding or
63      * not other nodes.
64      */

65    /**
66     * Some InputStreams do not support the {@link java.io.InputStream#reset}
67     * method, so we read it in completely and work on our Proxy.
68     */

69    InputStream JavaDoc _inputOctetStreamProxy = null;
70    /**
71     * The original NodeSet for this XMLSignatureInput
72     */

73    Set JavaDoc _inputNodeSet = null;
74    /**
75     * The original Element
76     */

77    Node JavaDoc _subNode=null;
78    /**
79     * Exclude Node *for enveloped transformations*
80     */

81    Node JavaDoc excludeNode=null;
82    /**
83     *
84     */

85    boolean excludeComments=false;
86    
87    boolean isNodeSet=false;
88    /**
89     * A cached bytes
90     */

91    byte []bytes=null;
92
93    /**
94     * Some Transforms may require explicit MIME type, charset (IANA registered "character set"), or other such information concerning the data they are receiving from an earlier Transform or the source data, although no Transform algorithm specified in this document needs such explicit information. Such data characteristics are provided as parameters to the Transform algorithm and should be described in the specification for the algorithm.
95     */

96    private String JavaDoc _MIMEType = null;
97
98    /**
99     * Field _SourceURI
100     */

101    private String JavaDoc _SourceURI = null;
102
103    /**
104     * Node Filter list.
105     */

106    List JavaDoc nodeFilters=new ArrayList JavaDoc();
107    
108    boolean needsToBeExpanded=false;
109    /**
110     * Check if the structured is needed to be circumbented.
111     * @return true if so.
112     */

113    public boolean isNeedsToBeExpanded() {
114        return needsToBeExpanded;
115    }
116    
117    /**
118     * Set if the structured is needed to be circumbented.
119     * @param needsToBeExpanded true if so.
120     */

121    public void setNeedsToBeExpanded(boolean needsToBeExpanded) {
122     this.needsToBeExpanded = needsToBeExpanded;
123    }
124    OutputStream JavaDoc outputStream=null;
125
126    /**
127     * Construct a XMLSignatureInput from an octet array.
128     * <p>
129     * This is a comfort method, which internally converts the byte[] array into an InputStream
130     * <p>NOTE: no defensive copy</p>
131     * @param inputOctets an octet array which including XML document or node
132     */

133    public XMLSignatureInput(byte[] inputOctets) {
134
135       // NO defensive copy
136

137       //this._inputOctetStreamProxy = new ByteArrayInputStream(inputOctets);
138
this.bytes=inputOctets;
139    }
140
141
142       /**
143     * Constructs a <code>XMLSignatureInput</code> from an octet stream. The
144     * stream is directly read.
145     *
146     * @param inputOctetStream
147     */

148    public XMLSignatureInput(InputStream JavaDoc inputOctetStream) {
149       this._inputOctetStreamProxy=inputOctetStream;
150       
151       //this(JavaUtils.getBytesFromStream(inputOctetStream));
152

153    }
154
155    /**
156     * Construct a XMLSignatureInput from a String.
157     * <p>
158     * This is a comfort method, which internally converts the String into a byte[] array using the {@link java.lang.String#getBytes()} method.
159     * @deprecated
160     * @param inputStr the input String which including XML document or node
161     */

162    public XMLSignatureInput(String JavaDoc inputStr) {
163       this(inputStr.getBytes());
164    }
165
166    /**
167     * Construct a XMLSignatureInput from a String with a given encoding.
168     * <p>
169     * This is a comfort method, which internally converts the String into a byte[] array using the {@link java.lang.String#getBytes()} method.
170     *
171     * @deprecated
172     * @param inputStr the input String with encoding <code>encoding</code>
173     * @param encoding the encoding of <code>inputStr</code>
174     * @throws UnsupportedEncodingException
175     */

176    public XMLSignatureInput(String JavaDoc inputStr, String JavaDoc encoding)
177            throws UnsupportedEncodingException JavaDoc {
178       this(inputStr.getBytes(encoding));
179    }
180
181    /**
182     * Construct a XMLSignatureInput from a subtree rooted by rootNode. This
183     * method included the node and <I>all</I> his descendants in the output.
184     *
185     * @param rootNode
186     */

187    public XMLSignatureInput(Node JavaDoc rootNode)
188    {
189       this._subNode = rootNode;
190    }
191
192    /**
193     * Constructor XMLSignatureInput
194     *
195     * @param inputNodeSet
196     * @param usedXPathAPI
197     */

198    public XMLSignatureInput(Set JavaDoc inputNodeSet) {
199        this._inputNodeSet = inputNodeSet;
200    }
201    
202    /**
203     * Returns the node set from input which was specified as the parameter of {@link XMLSignatureInput} constructor
204     *
205     * @return the node set
206     * @throws SAXException
207     * @throws IOException
208     * @throws ParserConfigurationException
209     * @throws CanonicalizationException
210     * @throws CanonicalizationException
211     * @throws IOException
212     * @throws ParserConfigurationException
213     * @throws SAXException
214     */

215    public Set JavaDoc getNodeSet() throws CanonicalizationException, ParserConfigurationException JavaDoc, IOException JavaDoc, SAXException JavaDoc {
216           return getNodeSet(false);
217    }
218    /**
219     * Returns the node set from input which was specified as the parameter of {@link XMLSignatureInput} constructor
220     * @param circunvent
221     *
222     * @return the node set
223     * @throws SAXException
224     * @throws IOException
225     * @throws ParserConfigurationException
226     * @throws CanonicalizationException
227     * @throws CanonicalizationException
228     * @throws IOException
229     * @throws ParserConfigurationException
230     * @throws SAXException
231     */

232    public Set JavaDoc getNodeSet(boolean circunvent)
233            throws ParserConfigurationException JavaDoc, IOException JavaDoc, SAXException JavaDoc,
234                   CanonicalizationException {
235       if (this._inputNodeSet!=null) {
236           return this._inputNodeSet;
237       }
238       if (this.isElement()) {
239             
240             if (circunvent) {
241                 XMLUtils.circumventBug2650(XMLUtils.getOwnerDocument(_subNode));
242             }
243             this._inputNodeSet = new HashSet JavaDoc();
244             XMLUtils.getSet(_subNode,this._inputNodeSet, excludeNode, this.excludeComments);
245             
246             return this._inputNodeSet;
247       }
248        else if (this.isOctetStream()) {
249          convertToNodes();
250          HashSet JavaDoc result=new HashSet JavaDoc();
251          XMLUtils.getSet(_subNode, result,null,false);
252             //this._inputNodeSet=result;
253
return result;
254       }
255
256       throw new RuntimeException JavaDoc(
257          "getNodeSet() called but no input data present");
258    }
259
260    /**
261     * Returns the Octect stream(byte Stream) from input which was specified as the parameter of {@link XMLSignatureInput} constructor
262     *
263     * @return the Octect stream(byte Stream) from input which was specified as the parameter of {@link XMLSignatureInput} constructor
264     * @throws IOException
265     */

266    public InputStream JavaDoc getOctetStream()
267            throws IOException JavaDoc {
268               
269       return getResetableInputStream();
270
271    }
272    /**
273      * @return real octect stream
274      */

275     public InputStream JavaDoc getOctetStreamReal () {
276        return this._inputOctetStreamProxy;
277    }
278    /**
279     * Returns the byte array from input which was specified as the parameter of {@link XMLSignatureInput} constructor
280     *
281     * @return the byte[] from input which was specified as the parameter of {@link XMLSignatureInput} constructor
282     *
283     * @throws CanonicalizationException
284     * @throws IOException
285     */

286    public byte[] getBytes()
287            throws IOException JavaDoc, CanonicalizationException {
288     if (bytes!=null) {
289         return bytes;
290       }
291       InputStream JavaDoc is = getResetableInputStream();
292       if (is!=null) {
293         //reseatable can read again bytes.
294
if (bytes==null) {
295             is.reset();
296             bytes=JavaUtils.getBytesFromStream(is);
297         }
298         return bytes;
299       }
300          Canonicalizer20010315OmitComments c14nizer =
301                 new Canonicalizer20010315OmitComments();
302         bytes=c14nizer.engineCanonicalize(this);
303         return bytes;
304    }
305
306
307    /**
308     * Determines if the object has been set up with a Node set
309     *
310     * @return true is the object has been set up with a Node set
311     */

312    public boolean isNodeSet() {
313       return (( (this._inputOctetStreamProxy == null)
314               && (this._inputNodeSet != null) ) || isNodeSet);
315    }
316    /**
317     * Determines if the object has been set up with an Element
318     *
319     * @return true is the object has been set up with a Node set
320     */

321    public boolean isElement() {
322         return ((this._inputOctetStreamProxy==null)&& (this._subNode!=null)
323                 && (this._inputNodeSet==null) && !isNodeSet
324                 );
325    }
326    
327    /**
328     * Determines if the object has been set up with an octet stream
329     *
330     * @return true is the object has been set up with an octet stream
331     */

332    public boolean isOctetStream() {
333       return ( ((this._inputOctetStreamProxy != null) || bytes!=null)
334               && ((this._inputNodeSet == null) && _subNode ==null));
335    }
336    
337    /**
338     * Determines if the object has been set up with a ByteArray
339     *
340     * @return true is the object has been set up with an octet stream
341     */

342    public boolean isByteArray() {
343       return ( (bytes!=null)
344               && ((this._inputNodeSet == null) && _subNode ==null));
345    }
346
347    /**
348     * Is the object correctly set up?
349     *
350     * @return true if the object has been set up correctly
351     */

352    public boolean isInitialized() {
353       return (this.isOctetStream() || this.isNodeSet());
354    }
355
356    /**
357     * Returns MIMEType
358     *
359     * @return MIMEType
360     */

361    public String JavaDoc getMIMEType() {
362       return this._MIMEType;
363    }
364
365    /**
366     * Sets MIMEType
367     *
368     * @param MIMEType
369     */

370    public void setMIMEType(String JavaDoc MIMEType) {
371       this._MIMEType = MIMEType;
372    }
373
374    /**
375     * Return SourceURI
376     *
377     * @return SourceURI
378     */

379    public String JavaDoc getSourceURI() {
380       return this._SourceURI;
381    }
382
383    /**
384     * Sets SourceURI
385     *
386     * @param SourceURI
387     */

388    public void setSourceURI(String JavaDoc SourceURI) {
389       this._SourceURI = SourceURI;
390    }
391
392    
393    /**
394     * Method toString
395     * @inheritDoc
396     *
397     */

398    public String JavaDoc toString() {
399
400       if (this.isNodeSet()) {
401          return "XMLSignatureInput/NodeSet/" + this._inputNodeSet.size()
402                    + " nodes/" + this.getSourceURI();
403       }
404       if (this.isElement()) {
405         return "XMLSignatureInput/Element/" + this._subNode
406         + " exclude "+ this.excludeNode + " comments:" +
407         this.excludeComments
408         +"/" + this.getSourceURI();
409       }
410          try {
411             return "XMLSignatureInput/OctetStream/" + this.getBytes().length
412                    + " octets/" + this.getSourceURI();
413          } catch (Exception JavaDoc ex) {
414             return "XMLSignatureInput/OctetStream//" + this.getSourceURI();
415          }
416       
417    }
418
419    /**
420     * Method getHTMLRepresentation
421     *
422     * @throws XMLSignatureException
423     * @return The HTML representation for this XMLSignature
424     */

425    public String JavaDoc getHTMLRepresentation() throws XMLSignatureException {
426
427       XMLSignatureInputDebugger db = new XMLSignatureInputDebugger(this);
428
429       return db.getHTMLRepresentation();
430    }
431
432    /**
433     * Method getHTMLRepresentation
434     *
435     * @param inclusiveNamespaces
436     * @throws XMLSignatureException
437     * @return The HTML representation for this XMLSignature
438     */

439    public String JavaDoc getHTMLRepresentation(Set JavaDoc inclusiveNamespaces)
440            throws XMLSignatureException {
441
442       XMLSignatureInputDebugger db = new XMLSignatureInputDebugger( this,
443                                         inclusiveNamespaces);
444
445       return db.getHTMLRepresentation();
446    }
447
448    /**
449     * Gets the exclude node of this XMLSignatureInput
450     * @return Returns the excludeNode.
451     */

452     public Node JavaDoc getExcludeNode() {
453        return excludeNode;
454     }
455     
456     /**
457      * Sets the exclude node of this XMLSignatureInput
458      * @param excludeNode The excludeNode to set.
459      */

460      public void setExcludeNode(Node JavaDoc excludeNode) {
461         this.excludeNode = excludeNode;
462      }
463
464      /**
465       * Gets the node of this XMLSignatureInput
466       * @return The excludeNode set.
467       */

468      public Node JavaDoc getSubNode() {
469         return _subNode;
470      }
471      /**
472       * @return Returns the excludeComments.
473       */

474      public boolean isExcludeComments() {
475         return excludeComments;
476      }
477      /**
478       * @param excludeComments The excludeComments to set.
479       */

480      public void setExcludeComments(boolean excludeComments) {
481         this.excludeComments = excludeComments;
482      }
483
484     /**
485      * @param diOs
486      * @throws IOException
487      * @throws CanonicalizationException
488      */

489     public void updateOutputStream(OutputStream JavaDoc diOs) throws CanonicalizationException, IOException JavaDoc {
490         if (diOs==outputStream) {
491             return;
492         }
493         if (bytes!=null) {
494             diOs.write(bytes);
495             return;
496          }else if (_inputOctetStreamProxy==null) {
497              Canonicalizer20010315OmitComments c14nizer =
498                     new Canonicalizer20010315OmitComments();
499              c14nizer.setWriter(diOs);
500             c14nizer.engineCanonicalize(this);
501             return;
502           } else {
503             InputStream JavaDoc is = getResetableInputStream();
504             if (bytes!=null) {
505                 //already read write it, can be rea.
506
diOs.write(bytes,0,bytes.length);
507                 return;
508             }
509             is.reset();
510             int num;
511             byte[] bytesT = new byte[1024];
512             while ((num=is.read(bytesT))>0) {
513                 diOs.write(bytesT,0,num);
514             }
515                 
516           }
517         
518     }
519
520
521     /**
522      * @param os
523      */

524     public void setOutputStream(OutputStream JavaDoc os) {
525         outputStream=os;
526         
527     }
528     protected InputStream JavaDoc getResetableInputStream() throws IOException JavaDoc{
529         if ((_inputOctetStreamProxy instanceof ByteArrayInputStream JavaDoc) ) {
530             if (!_inputOctetStreamProxy.markSupported()) {
531                 throw new RuntimeException JavaDoc("Accepted as Markable but not truly been"+_inputOctetStreamProxy);
532             }
533            return _inputOctetStreamProxy;
534         }
535         if (bytes!=null) {
536             _inputOctetStreamProxy=new ByteArrayInputStream JavaDoc(bytes);
537             return _inputOctetStreamProxy;
538         }
539         if (_inputOctetStreamProxy ==null)
540             return null;
541         if (_inputOctetStreamProxy.markSupported()) {
542             if (log.isLoggable(java.util.logging.Level.INFO)) log.log(java.util.logging.Level.INFO, "Mark Suported but not used as reset");
543         }
544         bytes=JavaUtils.getBytesFromStream(_inputOctetStreamProxy);
545         _inputOctetStreamProxy.close();
546         _inputOctetStreamProxy=new ByteArrayInputStream JavaDoc(bytes);
547         return _inputOctetStreamProxy;
548     }
549         
550
551     /**
552      * @param filter
553      */

554     public void addNodeFilter(NodeFilter filter) {
555         if (isOctetStream()) {
556             try {
557                 convertToNodes();
558             } catch (Exception JavaDoc e) {
559                 throw new XMLSecurityRuntimeException("signature.XMLSignatureInput.nodesetReference",e);
560             }
561         }
562         nodeFilters.add(filter);
563         
564     }
565
566     /**
567      * @return the node filters
568      */

569     public List JavaDoc getNodeFilters() {
570         // TODO Auto-generated method stub
571
return nodeFilters;
572     }
573
574     /**
575      * @param b
576      */

577     public void setNodeSet(boolean b) {
578         isNodeSet=b;
579         
580     }
581     
582     void convertToNodes() throws CanonicalizationException, ParserConfigurationException JavaDoc, IOException JavaDoc, SAXException JavaDoc{
583         DocumentBuilderFactory JavaDoc dfactory = DocumentBuilderFactory.newInstance();
584         dfactory.setValidating(false);
585         dfactory.setNamespaceAware(true);
586         DocumentBuilder JavaDoc db = dfactory.newDocumentBuilder();
587         // select all nodes, also the comments.
588
try {
589            db.setErrorHandler(new com.sun.org.apache.xml.internal.security.utils
590
              .IgnoreAllErrorHandler());
591
592            Document JavaDoc doc = db.parse(this.getOctetStream());
593            
594            XMLUtils.circumventBug2650(doc);
595            this._subNode=doc.getDocumentElement();
596         } catch (SAXException JavaDoc ex) {
597
598            // if a not-wellformed nodeset exists, put a container around it...
599
ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
600
601            baos.write("<container>".getBytes());
602            baos.write(this.getBytes());
603            baos.write("</container>".getBytes());
604
605            byte result[] = baos.toByteArray();
606            Document JavaDoc document = db.parse(new ByteArrayInputStream JavaDoc(result));
607            this._subNode=document.getDocumentElement().getFirstChild().getFirstChild();
608         }
609         this._inputOctetStreamProxy=null;
610         this.bytes=null;
611     }
612 }
613
Popular Tags