KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > c14n > implementations > CanonicalizerBase


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.c14n.implementations;
18
19
20
21 import java.io.ByteArrayOutputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.io.UnsupportedEncodingException JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.ListIterator JavaDoc;
29 import java.util.Set JavaDoc;
30
31 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
32 import javax.xml.parsers.ParserConfigurationException JavaDoc;
33
34 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
35 import com.sun.org.apache.xml.internal.security.c14n.CanonicalizerSpi;
36 import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare;
37 import com.sun.org.apache.xml.internal.security.signature.NodeFilter;
38 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
39 import com.sun.org.apache.xml.internal.security.utils.Constants;
40 import com.sun.org.apache.xml.internal.security.utils.UnsyncByteArrayOutputStream;
41 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
42 import org.w3c.dom.Attr JavaDoc;
43 import org.w3c.dom.Comment JavaDoc;
44 import org.w3c.dom.Document JavaDoc;
45 import org.w3c.dom.Element JavaDoc;
46 import org.w3c.dom.NamedNodeMap JavaDoc;
47 import org.w3c.dom.Node JavaDoc;
48 import org.w3c.dom.ProcessingInstruction JavaDoc;
49 import org.xml.sax.SAXException JavaDoc;
50
51
52 /**
53  * Abstract base class for canonicalization algorithms.
54  *
55  * @author Christian Geuer-Pollmann <geuerp@apache.org>
56  * @version $Revision: 1.23 $
57  */

58 public abstract class CanonicalizerBase extends CanonicalizerSpi {
59    //Constants to be outputed, In char array form, so
60
//less garbage is generate when outputed.
61
private static final byte[] _END_PI = {'?','>'};
62    private static final byte[] _BEGIN_PI = {'<','?'};
63    private static final byte[] _END_COMM = {'-','-','>'};
64    private static final byte[] _BEGIN_COMM = {'<','!','-','-'};
65    private static final byte[] __XA_ = {'&','#','x','A',';'};
66    private static final byte[] __X9_ = {'&','#','x','9',';'};
67    private static final byte[] _QUOT_ = {'&','q','u','o','t',';'};
68    private static final byte[] __XD_ = {'&','#','x','D',';'};
69    private static final byte[] _GT_ = {'&','g','t',';'};
70    private static final byte[] _LT_ = {'&','l','t',';'};
71    private static final byte[] _END_TAG = {'<','/'};
72    private static final byte[] _AMP_ = {'&','a','m','p',';'};
73    final static AttrCompare COMPARE=new AttrCompare();
74    final static String JavaDoc XML="xml";
75    final static String JavaDoc XMLNS="xmlns";
76    final static byte[] equalsStr= {'=','\"'};
77    static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
78    static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
79    static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
80    //The null xmlns definiton.
81
protected static final Attr JavaDoc nullNode;
82    static {
83     try {
84         nullNode=DocumentBuilderFactory.newInstance().
85             newDocumentBuilder().newDocument().createAttributeNS(Constants.NamespaceSpecNS,XMLNS);
86         nullNode.setValue("");
87     } catch (Exception JavaDoc e) {
88         throw new RuntimeException JavaDoc("Unable to create nullNode"/*,*/+e);
89     }
90    }
91    
92    List JavaDoc nodeFilter;
93    
94    boolean _includeComments;
95    Set JavaDoc _xpathNodeSet = null;
96    /**
97     * The node to be skiped/excluded from the DOM tree
98     * in subtree canonicalizations.
99     */

100    Node JavaDoc _excludeNode =null;
101    OutputStream JavaDoc _writer = new UnsyncByteArrayOutputStream();//null;
102

103    /**
104     * Constructor CanonicalizerBase
105     *
106     * @param includeComments
107     */

108    public CanonicalizerBase(boolean includeComments) {
109       this._includeComments = includeComments;
110    }
111
112    /**
113     * Method engineCanonicalizeSubTree
114     * @inheritDoc
115     * @param rootNode
116     * @throws CanonicalizationException
117     */

118    public byte[] engineCanonicalizeSubTree(Node JavaDoc rootNode)
119            throws CanonicalizationException {
120         return engineCanonicalizeSubTree(rootNode,(Node JavaDoc)null);
121    }
122    /**
123     * Canonicalizes a Subtree node.
124     * @param input the root of the subtree to canicalize
125     * @return The canonicalize stream.
126     * @throws CanonicalizationException
127     */

128     public byte[] engineCanonicalize(XMLSignatureInput input)
129     throws CanonicalizationException {
130         try {
131             if (input.isExcludeComments())
132                 _includeComments = false;
133             byte[] bytes;
134             if (input.isOctetStream()) {
135                 return engineCanonicalize(input.getBytes());
136             }
137             if (input.isElement()) {
138                 bytes = engineCanonicalizeSubTree(input.getSubNode(), input
139                         .getExcludeNode());
140                 return bytes;
141             } else if (input.isNodeSet()) {
142                 nodeFilter=input.getNodeFilters();
143                                 Document JavaDoc doc = null;
144                                 if (input.getSubNode() != null) {
145                                     doc=XMLUtils.getOwnerDocument(input.getSubNode());
146                                 } else {
147                                     doc=XMLUtils.getOwnerDocument(input.getNodeSet());
148                                 }
149                 if (input.isNeedsToBeExpanded()) {
150                     XMLUtils.circumventBug2650(doc);
151                 }
152
153                 if (input.getSubNode() != null) {
154                     bytes = engineCanonicalizeXPathNodeSetInternal(input.getSubNode());
155                 } else {
156                     bytes = engineCanonicalizeXPathNodeSet(input.getNodeSet());
157                 }
158                 return bytes;
159
160             }
161             return null;
162         } catch (CanonicalizationException ex) {
163             throw new CanonicalizationException("empty", ex);
164         } catch (ParserConfigurationException JavaDoc ex) {
165             throw new CanonicalizationException("empty", ex);
166         } catch (IOException JavaDoc ex) {
167             throw new CanonicalizationException("empty", ex);
168         } catch (SAXException JavaDoc ex) {
169             throw new CanonicalizationException("empty", ex);
170         }
171    }
172    /**
173      * Canonicalizes a Subtree node.
174      *
175      * @param rootNode
176      * the root of the subtree to canicalize
177      * @param excludeNode
178      * a node to be excluded from the canicalize operation
179      * @return The canonicalize stream.
180      * @throws CanonicalizationException
181      */

182     byte[] engineCanonicalizeSubTree(Node JavaDoc rootNode,Node JavaDoc excludeNode)
183     throws CanonicalizationException {
184         this._excludeNode = excludeNode;
185         try {
186          NameSpaceSymbTable ns=new NameSpaceSymbTable();
187          if (rootNode instanceof Element JavaDoc) {
188             //Fills the nssymbtable with the definitions of the parent of the root subnode
189
getParentNameSpaces((Element JavaDoc)rootNode,ns);
190          }
191          this.canonicalizeSubTree(rootNode,ns,rootNode);
192          this._writer.close();
193          if (this._writer instanceof ByteArrayOutputStream JavaDoc) {
194             byte []result=((ByteArrayOutputStream JavaDoc)this._writer).toByteArray();
195             if (reset) {
196                 ((ByteArrayOutputStream JavaDoc)this._writer).reset();
197             }
198             return result;
199          }
200          return null;
201          
202       } catch (UnsupportedEncodingException JavaDoc ex) {
203          throw new CanonicalizationException("empty", ex);
204       } catch (IOException JavaDoc ex) {
205          throw new CanonicalizationException("empty", ex);
206       }
207    }
208  
209    
210    /**
211     * Method canonicalizeSubTree, this function is a recursive one.
212     *
213     * @param currentNode
214     * @param ns
215     * @param endnode
216     * @throws CanonicalizationException
217     * @throws IOException
218     */

219     final void canonicalizeSubTree(Node JavaDoc currentNode, NameSpaceSymbTable ns,Node JavaDoc endnode)
220     throws CanonicalizationException, IOException JavaDoc {
221         Node JavaDoc sibling=null;
222         Node JavaDoc parentNode=null;
223         final OutputStream JavaDoc writer=this._writer;
224         final Node JavaDoc excludeNode=this._excludeNode;
225         final boolean includeComments=this._includeComments;
226         do {
227             switch (currentNode.getNodeType()) {
228             
229             case Node.DOCUMENT_TYPE_NODE :
230             default :
231                 break;
232             
233             case Node.ENTITY_NODE :
234             case Node.NOTATION_NODE :
235             case Node.ATTRIBUTE_NODE :
236                 // illegal node type during traversal
237
throw new CanonicalizationException("empty");
238
239             case Node.DOCUMENT_FRAGMENT_NODE :
240             case Node.DOCUMENT_NODE :
241                 ns.outputNodePush();
242                 //currentNode = currentNode.getFirstChild();
243
sibling= currentNode.getFirstChild();
244                 break;
245                 
246             case Node.COMMENT_NODE :
247                 if (includeComments) {
248                     outputCommentToWriter((Comment JavaDoc) currentNode, writer);
249                 }
250                 break;
251                 
252             case Node.PROCESSING_INSTRUCTION_NODE :
253                 outputPItoWriter((ProcessingInstruction JavaDoc) currentNode, writer);
254                 break;
255                 
256             case Node.TEXT_NODE :
257             case Node.CDATA_SECTION_NODE :
258                 outputTextToWriter(currentNode.getNodeValue(), writer);
259                 break;
260                 
261             case Node.ELEMENT_NODE :
262                 if (currentNode==excludeNode) {
263                     break;
264                 }
265                 Element JavaDoc currentElement = (Element JavaDoc) currentNode;
266                 //Add a level to the nssymbtable. So latter can be pop-back.
267
ns.outputNodePush();
268                 writer.write('<');
269                 String JavaDoc name=currentElement.getTagName();
270                 writeStringToUtf8(name,writer);
271                 
272                 Iterator JavaDoc attrs = this.handleAttributesSubtree(currentElement,ns);
273                 if (attrs!=null) {
274                     //we output all Attrs which are available
275
while (attrs.hasNext()) {
276                         Attr JavaDoc attr = (Attr JavaDoc) attrs.next();
277                         outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer);
278                     }
279                 }
280                 writer.write('>');
281                 sibling= currentNode.getFirstChild();
282                 if (sibling==null) {
283                     writer.write(_END_TAG);
284                     writeStringToUtf8(name,writer);
285                     writer.write('>');
286                     //We fineshed with this level, pop to the previous definitions.
287
ns.outputNodePop();
288                 if (parentNode != null) {
289                             sibling= currentNode.getNextSibling();
290                 }
291                 } else {
292                     parentNode=currentElement;
293                 }
294                 break;
295             }
296             while (sibling==null && parentNode!=null) {
297                 writer.write(_END_TAG);
298                 writeStringToUtf8(((Element JavaDoc)parentNode).getTagName(),writer);
299                 writer.write('>');
300                 //We fineshed with this level, pop to the previous definitions.
301
ns.outputNodePop();
302                 if (parentNode==endnode)
303                     return;
304                 sibling=parentNode.getNextSibling();
305                 parentNode=parentNode.getParentNode();
306                 if (!(parentNode instanceof Element JavaDoc)) {
307                     parentNode=null;
308                 }
309             }
310             if (sibling==null)
311                 return;
312             currentNode=sibling;
313             sibling=currentNode.getNextSibling();
314         } while(true);
315     }
316
317    /**
318     * Checks whether a Comment or ProcessingInstruction is before or after the
319     * document element. This is needed for prepending or appending "\n"s.
320     *
321     * @param currentNode comment or pi to check
322     * @return NODE_BEFORE_DOCUMENT_ELEMENT, NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT or NODE_AFTER_DOCUMENT_ELEMENT
323     * @see #NODE_BEFORE_DOCUMENT_ELEMENT
324     * @see #NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT
325     * @see #NODE_AFTER_DOCUMENT_ELEMENT
326     */

327    final static int getPositionRelativeToDocumentElement(Node JavaDoc currentNode) {
328             
329       if ((currentNode == null) ||
330             (currentNode.getParentNode().getNodeType() != Node.DOCUMENT_NODE) ) {
331          return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
332       }
333       Element JavaDoc documentElement = currentNode.getOwnerDocument().getDocumentElement();
334       if ( (documentElement == null) || (documentElement == currentNode) ){
335          return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
336       }
337       
338       for (Node JavaDoc x = currentNode; x != null; x = x.getNextSibling()) {
339          if (x == documentElement) {
340             return CanonicalizerBase.NODE_BEFORE_DOCUMENT_ELEMENT;
341          }
342       }
343
344       return CanonicalizerBase.NODE_AFTER_DOCUMENT_ELEMENT;
345    }
346      
347    /**
348     * Method engineCanonicalizeXPathNodeSet
349     * @inheritDoc
350     * @param xpathNodeSet
351     * @throws CanonicalizationException
352     */

353    public byte[] engineCanonicalizeXPathNodeSet(Set JavaDoc xpathNodeSet)
354            throws CanonicalizationException {
355        this._xpathNodeSet = xpathNodeSet;
356        return engineCanonicalizeXPathNodeSetInternal(XMLUtils.getOwnerDocument(this._xpathNodeSet));
357    }
358    private byte[] engineCanonicalizeXPathNodeSetInternal(Node JavaDoc doc)
359            throws CanonicalizationException {
360       
361       try {
362          this.canonicalizeXPathNodeSet(doc,doc);
363          this._writer.close();
364          if (this._writer instanceof ByteArrayOutputStream JavaDoc) {
365             byte [] sol=((ByteArrayOutputStream JavaDoc)this._writer).toByteArray();
366             if (reset) {
367                 ((ByteArrayOutputStream JavaDoc)this._writer).reset();
368             }
369             return sol;
370          }
371          return null;
372       } catch (UnsupportedEncodingException JavaDoc ex) {
373          throw new CanonicalizationException("empty", ex);
374       } catch (IOException JavaDoc ex) {
375          throw new CanonicalizationException("empty", ex);
376       }
377    }
378
379    /**
380     * Canoicalizes all the nodes included in the currentNode and contained in the
381     * _xpathNodeSet field.
382     *
383     * @param currentNode
384     * @param endnode
385     * @throws CanonicalizationException
386     * @throws IOException
387     */

388    final void canonicalizeXPathNodeSet(Node JavaDoc currentNode,Node JavaDoc endnode )
389            throws CanonicalizationException, IOException JavaDoc {
390        boolean currentNodeIsVisible = false;
391        NameSpaceSymbTable ns=new NameSpaceSymbTable();
392     Node JavaDoc sibling=null;
393     Node JavaDoc parentNode=null;
394     OutputStream JavaDoc writer=this._writer;
395     do {
396         switch (currentNode.getNodeType()) {
397         
398         case Node.DOCUMENT_TYPE_NODE :
399         default :
400             break;
401         
402         case Node.ENTITY_NODE :
403         case Node.NOTATION_NODE :
404         case Node.ATTRIBUTE_NODE :
405             // illegal node type during traversal
406
throw new CanonicalizationException("empty");
407
408         case Node.DOCUMENT_FRAGMENT_NODE :
409         case Node.DOCUMENT_NODE :
410             ns.outputNodePush();
411             //currentNode = currentNode.getFirstChild();
412
sibling= currentNode.getFirstChild();
413             break;
414             
415         case Node.COMMENT_NODE :
416             if (this._includeComments && isVisible(currentNode)) {
417                 outputCommentToWriter((Comment JavaDoc) currentNode, writer);
418             }
419             break;
420             
421         case Node.PROCESSING_INSTRUCTION_NODE :
422             if (isVisible(currentNode))
423                 outputPItoWriter((ProcessingInstruction JavaDoc) currentNode, writer);
424             break;
425             
426         case Node.TEXT_NODE :
427         case Node.CDATA_SECTION_NODE :
428             if (isVisible(currentNode)) {
429             outputTextToWriter(currentNode.getNodeValue(), writer);
430             for (Node JavaDoc nextSibling = currentNode.getNextSibling();
431                     (nextSibling != null)
432                     && ((nextSibling.getNodeType() == Node.TEXT_NODE)
433                         || (nextSibling.getNodeType()
434                             == Node.CDATA_SECTION_NODE));
435                     nextSibling = nextSibling.getNextSibling()) {
436                /* The XPath data model allows to select only the first of a
437                 * sequence of mixed text and CDATA nodes. But we must output
438                 * them all, so we must search:
439                 *
440                 * @see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6329
441                 */

442                outputTextToWriter(nextSibling.getNodeValue(), writer);
443                currentNode=nextSibling;
444                sibling=currentNode.getNextSibling();
445             }
446             
447             }
448             break;
449             
450         case Node.ELEMENT_NODE :
451             Element JavaDoc currentElement = (Element JavaDoc) currentNode;
452             //Add a level to the nssymbtable. So latter can be pop-back.
453
String JavaDoc name=null;
454             currentNodeIsVisible=isVisible(currentNode);
455             if (currentNodeIsVisible) {
456                 ns.outputNodePush();
457                 writer.write('<');
458                 name=currentElement.getTagName();
459                 writeStringToUtf8(name,writer);
460             } else {
461                 ns.push();
462             }
463             
464             Iterator JavaDoc attrs = handleAttributes(currentElement,ns);
465             if (attrs!=null) {
466                 //we output all Attrs which are available
467
while (attrs.hasNext()) {
468                     Attr JavaDoc attr = (Attr JavaDoc) attrs.next();
469                     outputAttrToWriter(attr.getNodeName(),attr.getNodeValue(), writer);
470                 }
471             }
472             if (currentNodeIsVisible) {
473                 writer.write('>');
474             }
475             sibling= currentNode.getFirstChild();
476         
477             if (sibling==null) {
478                 if (currentNodeIsVisible) {
479                     writer.write(_END_TAG);
480                     writeStringToUtf8(name,writer);
481                     writer.write('>');
482                     //We fineshed with this level, pop to the previous definitions.
483
ns.outputNodePop();
484                 } else {
485                     ns.pop();
486                 }
487                 if (parentNode != null) {
488                         sibling= currentNode.getNextSibling();
489                 }
490             } else {
491                 parentNode=currentElement;
492             }
493             break;
494         }
495         while (sibling==null && parentNode!=null) {
496             if (isVisible(parentNode)) {
497                 writer.write(_END_TAG);
498                 writeStringToUtf8(((Element JavaDoc)parentNode).getTagName(),writer);
499                 writer.write('>');
500                 //We fineshed with this level, pop to the previous definitions.
501
ns.outputNodePop();
502             } else {
503                 ns.pop();
504             }
505             if (parentNode==endnode)
506                 return;
507             sibling=parentNode.getNextSibling();
508             parentNode=parentNode.getParentNode();
509             if (!(parentNode instanceof Element JavaDoc)) {
510                 parentNode=null;
511             }
512         }
513         if (sibling==null)
514             return;
515         currentNode=sibling;
516         sibling=currentNode.getNextSibling();
517     } while(true);
518    }
519
520    boolean isVisible(Node JavaDoc currentNode) {
521        if (nodeFilter!=null) {
522         Iterator JavaDoc it=nodeFilter.iterator();
523         while (it.hasNext()) {
524             if (!((NodeFilter)it.next()).isNodeInclude(currentNode))
525                 return false;
526         }
527        }
528         if ((this._xpathNodeSet!=null) && !this._xpathNodeSet.contains(currentNode))
529             return false;
530         return true;
531     }
532
533     /**
534      * Adds to ns the definitons from the parent elements of el
535      * @param el
536      * @param ns
537      */

538     final static void getParentNameSpaces(Element JavaDoc el,NameSpaceSymbTable ns) {
539         List JavaDoc parents=new ArrayList JavaDoc();
540         Node JavaDoc n1=el.getParentNode();
541         if (!(n1 instanceof Element JavaDoc)) {
542             return;
543         }
544         //Obtain all the parents of the elemnt
545
Element JavaDoc parent=(Element JavaDoc) el.getParentNode();
546         while (parent!=null) {
547             parents.add(parent);
548             Node JavaDoc n=parent.getParentNode();
549             if (!(n instanceof Element JavaDoc )) {
550                 break;
551             }
552             parent=(Element JavaDoc)n;
553         }
554         //Visit them in reverse order.
555
ListIterator JavaDoc it=parents.listIterator(parents.size());
556         while (it.hasPrevious()) {
557         Element JavaDoc ele=(Element JavaDoc)it.previous();
558         if (!ele.hasAttributes()) {
559             continue;
560         }
561         NamedNodeMap JavaDoc attrs = ele.getAttributes();
562         int attrsLength = attrs.getLength();
563          for (int i = 0; i < attrsLength; i++) {
564             Attr JavaDoc N = (Attr JavaDoc) attrs.item(i);
565             if (!Constants.NamespaceSpecNS.equals(N.getNamespaceURI())) {
566                //Not a namespace definition, ignore.
567
continue;
568             }
569
570             String JavaDoc NName=N.getLocalName();
571             String JavaDoc NValue=N.getNodeValue();
572             if (XML.equals(NName)
573                     && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
574                continue;
575             }
576             ns.addMapping(NName,NValue,N);
577          }
578         }
579         Attr JavaDoc nsprefix;
580         if (((nsprefix=ns.getMappingWithoutRendered("xmlns"))!=null)
581                 && "".equals(nsprefix.getValue())) {
582              ns.addMappingAndRender("xmlns","",nullNode);
583         }
584     }
585    /**
586     * Outputs an Attribute to the internal Writer.
587     *
588     * The string value of the node is modified by replacing
589     * <UL>
590     * <LI>all ampersands (&) with <CODE>&amp;amp;</CODE></LI>
591     * <LI>all open angle brackets (<) with <CODE>&amp;lt;</CODE></LI>
592     * <LI>all quotation mark characters with <CODE>&amp;quot;</CODE></LI>
593     * <LI>and the whitespace characters <CODE>#x9</CODE>, #xA, and #xD, with character
594     * references. The character references are written in uppercase
595     * hexadecimal with no leading zeroes (for example, <CODE>#xD</CODE> is represented
596     * by the character reference <CODE>&amp;#xD;</CODE>)</LI>
597     * </UL>
598     *
599     * @param name
600     * @param value
601     * @param writer
602     * @throws IOException
603     */

604    static final void outputAttrToWriter(final String JavaDoc name, final String JavaDoc value, final OutputStream JavaDoc writer) throws IOException JavaDoc {
605       writer.write(' ');
606       writeStringToUtf8(name,writer);
607       writer.write(equalsStr);
608       byte []toWrite;
609       final int length = value.length();
610       for (int i=0;i < length; i++) {
611          char c = value.charAt(i);
612
613          switch (c) {
614
615          case '&' :
616             toWrite=_AMP_;
617             //writer.write(_AMP_);
618
break;
619
620          case '<' :
621             toWrite=_LT_;
622             //writer.write(_LT_);
623
break;
624
625          case '"' :
626             toWrite=_QUOT_;
627             //writer.write(_QUOT_);
628
break;
629
630          case 0x09 : // '\t'
631
toWrite=__X9_;
632             //writer.write(__X9_);
633
break;
634
635          case 0x0A : // '\n'
636
toWrite=__XA_;
637             //writer.write(__XA_);
638
break;
639
640          case 0x0D : // '\r'
641
toWrite=__XD_;
642             //writer.write(__XD_);
643
break;
644
645          default :
646             writeCharToUtf8(c,writer);
647             //this._writer.write(c);
648
continue;
649          }
650          writer.write(toWrite);
651       }
652
653       writer.write('\"');
654    }
655
656    final static void writeCharToUtf8(final char c,final OutputStream JavaDoc out) throws IOException JavaDoc{
657     char ch;
658     if (/*(c >= 0x0001) &&*/ (c <= 0x007F)) {
659         out.write(c);
660         return;
661     }
662     int bias;
663     int write;
664     if (c > 0x07FF) {
665         ch=(char)(c>>>12);
666         write=0xE0;
667         if (ch>0) {
668             write |= ( ch & 0x0F);
669         }
670         out.write(write);
671         write=0x80;
672         bias=0x3F;
673     } else {
674         write=0xC0;
675         bias=0x1F;
676     }
677     ch=(char)(c>>>6);
678     if (ch>0) {
679          write|= (ch & bias);
680     }
681     out.write(write);
682     out.write(0x80 | ((c) & 0x3F));
683     
684    }
685    
686    final static void writeStringToUtf8(final String JavaDoc str,final OutputStream JavaDoc out) throws IOException JavaDoc{
687     final int length=str.length();
688     int i=0;
689     char c;
690     while (i<length) {
691         c=str.charAt(i++);
692         if (/*(c >= 0x0001) &&*/ (c <= 0x007F)) {
693             out.write(c);
694             continue;
695         }
696         char ch;
697         int bias;
698         int write;
699         if (c > 0x07FF) {
700             ch=(char)(c>>>12);
701             write=0xE0;
702             if (ch>0) {
703                 write |= ( ch & 0x0F);
704             }
705             out.write(write);
706             write=0x80;
707             bias=0x3F;
708         } else {
709             write=0xC0;
710             bias=0x1F;
711         }
712         ch=(char)(c>>>6);
713         if (ch>0) {
714              write|= (ch & bias);
715         }
716         out.write(write);
717         out.write(0x80 | ((c) & 0x3F));
718         continue;
719                 
720     }
721     
722    }
723    /**
724     * Outputs a PI to the internal Writer.
725     *
726     * @param currentPI
727     * @param writer where to write the things
728     * @throws IOException
729     */

730    static final void outputPItoWriter(ProcessingInstruction JavaDoc currentPI, OutputStream JavaDoc writer) throws IOException JavaDoc {
731       final int position = getPositionRelativeToDocumentElement(currentPI);
732
733       if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
734         writer.write('\n');
735       }
736       writer.write(_BEGIN_PI);
737
738       final String JavaDoc target = currentPI.getTarget();
739       int length = target.length();
740
741       for (int i = 0; i < length; i++) {
742          char c=target.charAt(i);
743          if (c==0x0D) {
744             writer.write(__XD_);
745          } else {
746             writeCharToUtf8(c,writer);
747          }
748       }
749
750       final String JavaDoc data = currentPI.getData();
751      
752       length = data.length();
753
754       if (length > 0) {
755          writer.write(' ');
756
757          for (int i = 0; i < length; i++) {
758             char c=data.charAt(i);
759             if (c==0x0D) {
760                writer.write(__XD_);
761             } else {
762                writeCharToUtf8(c,writer);
763             }
764          }
765       }
766
767       writer.write(_END_PI);
768       if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
769         writer.write('\n');
770      }
771    }
772
773    /**
774     * Method outputCommentToWriter
775     *
776     * @param currentComment
777     * @param writer writer where to write the things
778     * @throws IOException
779     */

780    static final void outputCommentToWriter(Comment JavaDoc currentComment, OutputStream JavaDoc writer) throws IOException JavaDoc {
781       final int position = getPositionRelativeToDocumentElement(currentComment);
782       if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
783         writer.write('\n');
784       }
785       writer.write(_BEGIN_COMM);
786
787       final String JavaDoc data = currentComment.getData();
788       final int length = data.length();
789
790       for (int i = 0; i < length; i++) {
791          char c=data.charAt(i);
792          if (c==0x0D) {
793             writer.write(__XD_);
794          } else {
795             writeCharToUtf8(c,writer);
796          }
797       }
798
799       writer.write(_END_COMM);
800       if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
801         writer.write('\n');
802      }
803    }
804
805    /**
806     * Outputs a Text of CDATA section to the internal Writer.
807     *
808     * @param text
809     * @param writer writer where to write the things
810     * @throws IOException
811     */

812    static final void outputTextToWriter(final String JavaDoc text, final OutputStream JavaDoc writer) throws IOException JavaDoc {
813       final int length = text.length();
814       byte []toWrite;
815       for (int i = 0; i < length; i++) {
816          char c = text.charAt(i);
817
818          switch (c) {
819
820          case '&' :
821             toWrite=_AMP_;
822             //writer.write(_AMP_);
823
break;
824
825          case '<' :
826             toWrite=_LT_;
827             //writer.write(_LT_);
828
break;
829
830          case '>' :
831             toWrite=_GT_;
832             //writer.write(_GT_);
833
break;
834
835          case 0xD :
836             toWrite=__XD_;
837             //writer.write(__XD_);
838
break;
839
840          default :
841             writeCharToUtf8(c,writer);
842             continue;
843          }
844          writer.write(toWrite);
845       }
846    }
847
848    /**
849     * Obtain the attributes to output for this node in XPathNodeSet c14n.
850     *
851     * @param E
852     * @param ns
853     * @return the attributes nodes to output.
854     * @throws CanonicalizationException
855     */

856    abstract Iterator JavaDoc handleAttributes(Element JavaDoc E, NameSpaceSymbTable ns )
857    throws CanonicalizationException;
858
859    /**
860     * Obtain the attributes to output for this node in a Subtree c14n.
861     *
862     * @param E
863     * @param ns
864     * @return the attributes nodes to output.
865     * @throws CanonicalizationException
866     */

867    abstract Iterator JavaDoc handleAttributesSubtree(Element JavaDoc E, NameSpaceSymbTable ns)
868    throws CanonicalizationException;
869
870
871     
872     /**
873      * @param _writer The _writer to set.
874      */

875     public void setWriter(OutputStream JavaDoc _writer) {
876         this._writer = _writer;
877     }
878      
879 }
880
Popular Tags