You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by ra...@apache.org on 2006/08/05 18:58:30 UTC
svn commit: r429012 - in
/xml/security/trunk/src/org/apache/xml/security/c14n/implementations:
Canonicalizer20010315.java CanonicalizerBase.java UtfHelpper.java
Author: raul
Date: Sat Aug 5 09:58:30 2006
New Revision: 429012
URL: http://svn.apache.org/viewvc?rev=429012&view=rev
Log:
Optimize xml:* inheritance
Refactor utf writting.
Added:
xml/security/trunk/src/org/apache/xml/security/c14n/implementations/UtfHelpper.java
Modified:
xml/security/trunk/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315.java
xml/security/trunk/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java
Modified: xml/security/trunk/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315.java?rev=429012&r1=429011&r2=429012&view=diff
==============================================================================
--- xml/security/trunk/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315.java (original)
+++ xml/security/trunk/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315.java Sat Aug 5 09:58:30 2006
@@ -20,8 +20,11 @@
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@@ -54,7 +57,85 @@
final SortedSet result= new TreeSet(COMPARE);
static final String XMLNS_URI=Constants.NamespaceSpecNS;
static final String XML_LANG_URI=Constants.XML_LANG_SPACE_SpecNS;
- /**
+ static class XmlAttrStack {
+ int currentLevel=0;
+ int lastlevel=0;
+ XmlsStackElement cur;
+ static class XmlsStackElement {
+ int level;
+ boolean rendered=false;
+ List nodes=new ArrayList();
+ };
+ List levels=new ArrayList();
+ void push(int level) {
+ currentLevel=level;
+ if (currentLevel==-1)
+ return;
+ cur=null;
+ while (lastlevel>currentLevel) {
+ levels.remove(levels.size()-1);
+ if (levels.size()==0) {
+ lastlevel=0;
+ return;
+ }
+ lastlevel=((XmlsStackElement)levels.get(levels.size()-1)).level;
+ }
+ }
+ void addXmlnsAttr(Attr n) {
+ if (cur==null) {
+ cur=new XmlsStackElement();
+ cur.level=currentLevel;
+ levels.add(cur);
+ lastlevel=currentLevel;
+ }
+ cur.nodes.add(n);
+ }
+ void getXmlnsAttr(Collection col) {
+ int size=levels.size()-1;
+ if (cur==null) {
+ cur=new XmlsStackElement();
+ cur.level=currentLevel;
+ lastlevel=currentLevel;
+ levels.add(cur);
+ }
+ boolean parentRendered=false;
+ XmlsStackElement e=null;
+ if (size==-1) {
+ parentRendered=true;
+ } else {
+ e=(XmlsStackElement)levels.get(size);
+ if (e.rendered && e.level+1==currentLevel)
+ parentRendered=true;
+
+ }
+ if (parentRendered) {
+ col.addAll(cur.nodes);
+ cur.rendered=true;
+ return;
+ }
+
+ Map loa = new HashMap();
+ for (;size>=0;size--) {
+ e=(XmlsStackElement)levels.get(size);
+ Iterator it=e.nodes.iterator();
+ while (it.hasNext()) {
+ Attr n=(Attr)it.next();
+ if (!loa.containsKey(n.getName()))
+ loa.put(n.getName(),n);
+ }
+ //if (e.rendered)
+ //break;
+
+ };
+ //cur.nodes.clear();
+ //cur.nodes.addAll(loa.values());
+ cur.rendered=true;
+ col.addAll(loa.values());
+ }
+
+ }
+ XmlAttrStack xmlattrStack=new XmlAttrStack();
+ /**
* Constructor Canonicalizer20010315
*
* @param includeComments
@@ -124,54 +205,14 @@
//Obtain all the namespaces defined in the parents, and added to the output.
ns.getUnrenderedNodes(result);
//output the attributes in the xml namespace.
- addXmlAttributesSubtree(E, result);
- firstCall=false;
+ xmlattrStack.getXmlnsAttr(result);
+ firstCall=false;
}
return result.iterator();
}
/**
- * Float the xml:* attributes of the parent nodes to the root node of c14n
- * @param E the root node.
- * @param result the xml:* attributes to output.
- */
- private void addXmlAttributesSubtree(Element E, SortedSet result) {
- // E is in the node-set
- Node parent = E.getParentNode();
- Map loa = new HashMap();
-
- if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)) {
- // parent element is not in node set
- for (Node ancestor = parent;
- (ancestor != null)
- && (ancestor.getNodeType() == Node.ELEMENT_NODE);
- ancestor = ancestor.getParentNode()) {
- Element el=((Element) ancestor);
- if (!el.hasAttributes()) {
- continue;
- }
- // for all ancestor elements
- NamedNodeMap ancestorAttrs = el.getAttributes();
- int length=ancestorAttrs.getLength();
- for (int i = 0; i < length; i++) {
- // for all attributes in the ancestor element
- Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i);
- if (XML_LANG_URI==currentAncestorAttr.getNamespaceURI()) {
- String name=currentAncestorAttr.getName();
- if (!loa.containsKey(name) ) {
- loa.put(name, currentAncestorAttr);
- }
- }
- }
- }
- }
-
- result.addAll( loa.values());
-
- }
-
- /**
* Returns the Attr[]s to be outputted for the given element.
* <br>
* IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has
@@ -185,6 +226,7 @@
*/
Iterator handleAttributes(Element E, NameSpaceSymbTable ns ) throws CanonicalizationException {
// result will contain the attrs which have to be outputted
+ xmlattrStack.push(ns.getLevel());
boolean isRealVisible=isVisibleDO(E,ns.getLevel())==1;
NamedNodeMap attrs = null;
int attrsLength = 0;
@@ -203,10 +245,12 @@
if (XMLNS_URI!=NUri) {
//A non namespace definition node.
- if (isRealVisible){
+ if (XML_LANG_URI==NUri) {
+ xmlattrStack.addXmlnsAttr(N);
+ } else if (isRealVisible){
//The node is visible add the attribute to the list of output attributes.
result.add(N);
- }
+ }
//keep working
continue;
}
@@ -262,7 +306,8 @@
result.add(n);
}
//Float all xml:* attributes of the unselected parent elements to this one.
- addXmlAttributes(E,result);
+ //addXmlAttributes(E,result);
+ xmlattrStack.getXmlnsAttr(result);
ns.getUnrenderedNodes(result);
}
@@ -270,61 +315,6 @@
return result.iterator();
}
/**
- * Float the xml:* attributes of the unselected parent nodes to the ciurrent node.
- * @param E
- * @param result
- */
- private void addXmlAttributes(Element E, SortedSet result) {
- /* The processing of an element node E MUST be modified slightly when an
- * XPath node-set is given as input and the element's parent is omitted
- * from the node-set. The method for processing the attribute axis of an
- * element E in the node-set is enhanced. All element nodes along E's
- * ancestor axis are examined for nearest occurrences of attributes in
- * the xml namespace, such as xml:lang and xml:space (whether or not they
- * are in the node-set). From this list of attributes, remove any that are
- * in E's attribute axis (whether or not they are in the node-set). Then,
- * lexicographically merge this attribute list with the nodes of E's
- * attribute axis that are in the node-set. The result of visiting the
- * attribute axis is computed by processing the attribute nodes in this
- * merged attribute list.
- */
-
- // E is in the node-set
- Node parent = E.getParentNode();
- Map loa = new HashMap();
-
- if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)
- &&!isVisible(parent)) {
-
- // parent element is not in node set
- for (Node ancestor = parent;
- (ancestor != null)
- && (ancestor.getNodeType() == Node.ELEMENT_NODE);
- ancestor = ancestor.getParentNode()) {
- Element el=((Element) ancestor);
- if (!el.hasAttributes()) {
- continue;
- }
- // for all ancestor elements
- NamedNodeMap ancestorAttrs =el.getAttributes();
- int length=ancestorAttrs.getLength();
- for (int i = 0; i < length; i++) {
- // for all attributes in the ancestor element
- Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i);
- if (XML_LANG_URI==currentAncestorAttr.getNamespaceURI()) {
- String name=currentAncestorAttr.getName();
- if (!loa.containsKey(name) ) {
- loa.put(name, currentAncestorAttr);
- }
- }
- }
- }
- }
- result.addAll(loa.values());
-
-}
-
- /**
* Always throws a CanonicalizationException because this is inclusive c14n.
*
* @param xpathNodeSet
@@ -366,5 +356,32 @@
}
XMLUtils.circumventBug2650(doc);
+ }
+
+ void handleParent(Element e, NameSpaceSymbTable ns) {
+ if (!e.hasAttributes()) {
+ return;
+ }
+ xmlattrStack.push(-1);
+ NamedNodeMap attrs = e.getAttributes();
+ int attrsLength = attrs.getLength();
+ for (int i = 0; i < attrsLength; i++) {
+ Attr N = (Attr) attrs.item(i);
+ if (Constants.NamespaceSpecNS!=N.getNamespaceURI()) {
+ //Not a namespace definition, ignore.
+ if (XML_LANG_URI==N.getNamespaceURI()) {
+ xmlattrStack.addXmlnsAttr(N);
+ }
+ continue;
+ }
+
+ String NName=N.getLocalName();
+ String NValue=N.getNodeValue();
+ if (XML.equals(NName)
+ && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
+ continue;
+ }
+ ns.addMapping(NName,NValue,N);
+ }
}
}
Modified: xml/security/trunk/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java?rev=429012&r1=429011&r2=429012&view=diff
==============================================================================
--- xml/security/trunk/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java (original)
+++ xml/security/trunk/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java Sat Aug 5 09:58:30 2006
@@ -121,6 +121,18 @@
return engineCanonicalizeSubTree(rootNode,(Node)null);
}
/**
+ * Method engineCanonicalizeXPathNodeSet
+ * @inheritDoc
+ * @param xpathNodeSet
+ * @throws CanonicalizationException
+ */
+ public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet)
+ throws CanonicalizationException {
+ this._xpathNodeSet = xpathNodeSet;
+ return engineCanonicalizeXPathNodeSetInternal(XMLUtils.getOwnerDocument(this._xpathNodeSet));
+ }
+
+ /**
* Canonicalizes a Subtree node.
* @param input the root of the subtree to canicalize
* @return The canonicalize stream.
@@ -144,7 +156,6 @@
circumventBugIfNeeded(input);
-
if (input.getSubNode() != null) {
bytes = engineCanonicalizeXPathNodeSetInternal(input.getSubNode());
} else {
@@ -165,6 +176,13 @@
}
}
/**
+ * @param _writer The _writer to set.
+ */
+ public void setWriter(OutputStream _writer) {
+ this._writer = _writer;
+ }
+
+ /**
* Canonicalizes a Subtree node.
*
* @param rootNode
@@ -229,7 +247,6 @@
final OutputStream writer=this._writer;
final Node excludeNode=this._excludeNode;
final boolean includeComments=this._includeComments;
- boolean inElement=(documentLevel==NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT);
Map cache=new HashMap();
do {
switch (currentNode.getNodeType()) {
@@ -252,12 +269,12 @@
case Node.COMMENT_NODE :
if (includeComments) {
- outputCommentToWriter((Comment) currentNode, writer,inElement? NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT : documentLevel);
+ outputCommentToWriter((Comment) currentNode, writer, documentLevel);
}
break;
case Node.PROCESSING_INSTRUCTION_NODE :
- outputPItoWriter((ProcessingInstruction) currentNode, writer,inElement? NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT : documentLevel);
+ outputPItoWriter((ProcessingInstruction) currentNode, writer, documentLevel);
break;
case Node.TEXT_NODE :
@@ -266,7 +283,7 @@
break;
case Node.ELEMENT_NODE :
- inElement=true;
+ documentLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
if (currentNode==excludeNode) {
break;
}
@@ -275,7 +292,7 @@
ns.outputNodePush();
writer.write('<');
String name=currentElement.getTagName();
- writeByte(name,writer,cache);
+ UtfHelpper.writeByte(name,writer,cache);
Iterator attrs = this.handleAttributesSubtree(currentElement,ns);
if (attrs!=null) {
@@ -289,7 +306,7 @@
sibling= currentNode.getFirstChild();
if (sibling==null) {
writer.write(_END_TAG);
- writeStringToUtf8(name,writer);
+ UtfHelpper.writeStringToUtf8(name,writer);
writer.write('>');
//We fineshed with this level, pop to the previous definitions.
ns.outputNodePop();
@@ -303,7 +320,7 @@
}
while (sibling==null && parentNode!=null) {
writer.write(_END_TAG);
- writeByte(((Element)parentNode).getTagName(),writer,cache);
+ UtfHelpper.writeByte(((Element)parentNode).getTagName(),writer,cache);
writer.write('>');
//We fineshed with this level, pop to the previous definitions.
ns.outputNodePop();
@@ -313,7 +330,6 @@
parentNode=parentNode.getParentNode();
if (!(parentNode instanceof Element)) {
documentLevel=NODE_AFTER_DOCUMENT_ELEMENT;
- inElement=false;
parentNode=null;
}
}
@@ -326,17 +342,6 @@
- /**
- * Method engineCanonicalizeXPathNodeSet
- * @inheritDoc
- * @param xpathNodeSet
- * @throws CanonicalizationException
- */
- public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet)
- throws CanonicalizationException {
- this._xpathNodeSet = xpathNodeSet;
- return engineCanonicalizeXPathNodeSetInternal(XMLUtils.getOwnerDocument(this._xpathNodeSet));
- }
private byte[] engineCanonicalizeXPathNodeSetInternal(Node doc)
throws CanonicalizationException {
@@ -385,7 +390,6 @@
Node parentNode=null;
OutputStream writer=this._writer;
int documentLevel=NODE_BEFORE_DOCUMENT_ELEMENT;
- boolean inElement=false;
Map cache=new HashMap();
do {
switch (currentNode.getNodeType()) {
@@ -409,13 +413,13 @@
case Node.COMMENT_NODE :
if (this._includeComments && (isVisibleDO(currentNode,ns.getLevel())==1)) {
- outputCommentToWriter((Comment) currentNode, writer,inElement? NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT : documentLevel);
+ outputCommentToWriter((Comment) currentNode, writer, documentLevel);
}
break;
case Node.PROCESSING_INSTRUCTION_NODE :
if (isVisible(currentNode))
- outputPItoWriter((ProcessingInstruction) currentNode, writer,inElement? NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT : documentLevel);
+ outputPItoWriter((ProcessingInstruction) currentNode, writer, documentLevel);
break;
case Node.TEXT_NODE :
@@ -437,7 +441,6 @@
break;
case Node.ELEMENT_NODE :
- inElement=true;
documentLevel=NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
Element currentElement = (Element) currentNode;
//Add a level to the nssymbtable. So latter can be pop-back.
@@ -452,7 +455,7 @@
ns.outputNodePush();
writer.write('<');
name=currentElement.getTagName();
- writeByte(name,writer,cache);
+ UtfHelpper.writeByte(name,writer,cache);
} else {
ns.push();
}
@@ -473,7 +476,7 @@
if (sibling==null) {
if (currentNodeIsVisible) {
writer.write(_END_TAG);
- writeByte(name,writer,cache);
+ UtfHelpper.writeByte(name,writer,cache);
writer.write('>');
//We fineshed with this level, pop to the previous definitions.
ns.outputNodePop();
@@ -491,7 +494,7 @@
while (sibling==null && parentNode!=null) {
if (isVisible(parentNode)) {
writer.write(_END_TAG);
- writeByte(((Element)parentNode).getTagName(),writer,cache);
+ UtfHelpper.writeByte(((Element)parentNode).getTagName(),writer,cache);
writer.write('>');
//We fineshed with this level, pop to the previous definitions.
ns.outputNodePop();
@@ -504,7 +507,6 @@
parentNode=parentNode.getParentNode();
if (!(parentNode instanceof Element)) {
parentNode=null;
- inElement=false;
documentLevel=NODE_AFTER_DOCUMENT_ELEMENT;
}
}
@@ -554,12 +556,35 @@
return true;
}
+ void handleParent(Element e,NameSpaceSymbTable ns) {
+ if (!e.hasAttributes()) {
+ return;
+ }
+ NamedNodeMap attrs = e.getAttributes();
+ int attrsLength = attrs.getLength();
+ for (int i = 0; i < attrsLength; i++) {
+ Attr N = (Attr) attrs.item(i);
+ if (Constants.NamespaceSpecNS!=N.getNamespaceURI()) {
+ //Not a namespace definition, ignore.
+ continue;
+ }
+
+ String NName=N.getLocalName();
+ String NValue=N.getNodeValue();
+ if (XML.equals(NName)
+ && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
+ continue;
+ }
+ ns.addMapping(NName,NValue,N);
+ }
+ }
+
/**
* Adds to ns the definitons from the parent elements of el
* @param el
* @param ns
*/
- final static void getParentNameSpaces(Element el,NameSpaceSymbTable ns) {
+ final void getParentNameSpaces(Element el,NameSpaceSymbTable ns) {
List parents=new ArrayList(10);
Node n1=el.getParentNode();
if (!(n1 instanceof Element)) {
@@ -579,27 +604,8 @@
ListIterator it=parents.listIterator(parents.size());
while (it.hasPrevious()) {
Element ele=(Element)it.previous();
- if (!ele.hasAttributes()) {
- continue;
- }
- NamedNodeMap attrs = ele.getAttributes();
- int attrsLength = attrs.getLength();
- for (int i = 0; i < attrsLength; i++) {
- Attr N = (Attr) attrs.item(i);
- if (Constants.NamespaceSpecNS!=N.getNamespaceURI()) {
- //Not a namespace definition, ignore.
- continue;
- }
-
- String NName=N.getLocalName();
- String NValue=N.getNodeValue();
- if (XML.equals(NName)
- && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
- continue;
- }
- ns.addMapping(NName,NValue,N);
- }
- }
+ handleParent(ele, ns);
+ }
Attr nsprefix;
if (((nsprefix=ns.getMappingWithoutRendered("xmlns"))!=null)
&& "".equals(nsprefix.getValue())) {
@@ -607,320 +613,6 @@
}
}
/**
- * Outputs an Attribute to the internal Writer.
- *
- * The string value of the node is modified by replacing
- * <UL>
- * <LI>all ampersands (&) with <CODE>&amp;</CODE></LI>
- * <LI>all open angle brackets (<) with <CODE>&lt;</CODE></LI>
- * <LI>all quotation mark characters with <CODE>&quot;</CODE></LI>
- * <LI>and the whitespace characters <CODE>#x9</CODE>, #xA, and #xD, with character
- * references. The character references are written in uppercase
- * hexadecimal with no leading zeroes (for example, <CODE>#xD</CODE> is represented
- * by the character reference <CODE>&#xD;</CODE>)</LI>
- * </UL>
- *
- * @param name
- * @param value
- * @param writer
- * @throws IOException
- */
- static final void outputAttrToWriter(final String name, final String value, final OutputStream writer,
- final Map cache) throws IOException {
- writer.write(' ');
- writeByte(name,writer,cache);
- writer.write(equalsStr);
- byte []toWrite;
- final int length = value.length();
- int i=0;
- while (i < length) {
- char c = value.charAt(i++);
-
- switch (c) {
-
- case '&' :
- toWrite=_AMP_;
- break;
-
- case '<' :
- toWrite=_LT_;
- break;
-
- case '"' :
- toWrite=_QUOT_;
- break;
-
- case 0x09 : // '\t'
- toWrite=__X9_;
- break;
-
- case 0x0A : // '\n'
- toWrite=__XA_;
- break;
-
- case 0x0D : // '\r'
- toWrite=__XD_;
- break;
-
- default :
- if( (c & 0x80) ==0) {
- writer.write(c);
- } else {
- writeCharToUtf8(c,writer);
- };
- continue;
- }
- writer.write(toWrite);
- }
-
- writer.write('\"');
- }
-
- final static void writeCharToUtf8(final char c,final OutputStream out) throws IOException{
- if ( (c & 0x80) ==0) {
- out.write(c);
- return;
- }
- int bias;
- int write;
- char ch;
- if (c > 0x07FF) {
- ch=(char)(c>>>12);
- write=0xE0;
- if (ch>0) {
- write |= ( ch & 0x0F);
- }
- out.write(write);
- write=0x80;
- bias=0x3F;
- } else {
- write=0xC0;
- bias=0x1F;
- }
- ch=(char)(c>>>6);
- if (ch>0) {
- write|= (ch & bias);
- }
- out.write(write);
- out.write(0x80 | ((c) & 0x3F));
-
- }
- final static void writeByte(final String str,final OutputStream out,Map cache) throws IOException {
- byte []result=(byte[]) cache.get(str);
- if (result==null) {
- result=getStringInUtf8(str);
- cache.put(str,result);
- }
-
- out.write(result);
-
- }
- final static byte[] getStringInUtf8(final String str) {
- final int length=str.length();
- byte []result=new byte[length];
- int i=0;
- int out=0;
- char c;
- while (i<length) {
- c=str.charAt(i++);
- if ((c & 0x80) == 0) {
- result[out++]=(byte)c;
- continue;
- }
- char ch;
- int bias;
- byte write;
- if (c > 0x07FF) {
- ch=(char)(c>>>12);
- write=(byte)0xE0;
- if (ch>0) {
- write |= ( ch & 0x0F);
- }
- result[out++]=write;
- write=(byte)0x80;
- bias=0x3F;
- } else {
- write=(byte)0xC0;
- bias=0x1F;
- }
- ch=(char)(c>>>6);
- if (ch>0) {
- write|= (ch & bias);
- }
- result[out++]=write;
- result[out++]=(byte)(0x80 | ((c) & 0x3F));
-
- }
- return result;
- }
- final static void writeStringToUtf8(final String str,final OutputStream out) throws IOException{
- final int length=str.length();
- int i=0;
- char c;
- while (i<length) {
- c=str.charAt(i++);
- if ((c & 0x80) == 0) {
- out.write(c);
- continue;
- }
- char ch;
- int bias;
- int write;
- if (c > 0x07FF) {
- ch=(char)(c>>>12);
- write=0xE0;
- if (ch>0) {
- write |= ( ch & 0x0F);
- }
- out.write(write);
- write=0x80;
- bias=0x3F;
- } else {
- write=0xC0;
- bias=0x1F;
- }
- ch=(char)(c>>>6);
- if (ch>0) {
- write|= (ch & bias);
- }
- out.write(write);
- out.write(0x80 | ((c) & 0x3F));
-
- }
-
- }
- /**
- * Outputs a PI to the internal Writer.
- *
- * @param currentPI
- * @param writer where to write the things
- * @throws IOException
- */
- static final void outputPItoWriter(ProcessingInstruction currentPI, OutputStream writer,int position) throws IOException {
-
- if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
- writer.write('\n');
- }
- writer.write(_BEGIN_PI);
-
- final String target = currentPI.getTarget();
- int length = target.length();
-
- for (int i = 0; i < length; i++) {
- char c=target.charAt(i);
- if (c==0x0D) {
- writer.write(__XD_);
- } else {
- if( (c & 0x80) ==0) {
- writer.write(c);
- } else {
- writeCharToUtf8(c,writer);
- };
- }
- }
-
- final String data = currentPI.getData();
-
- length = data.length();
-
- if (length > 0) {
- writer.write(' ');
-
- for (int i = 0; i < length; i++) {
- char c=data.charAt(i);
- if (c==0x0D) {
- writer.write(__XD_);
- } else {
- writeCharToUtf8(c,writer);
- }
- }
- }
-
- writer.write(_END_PI);
- if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
- writer.write('\n');
- }
- }
-
- /**
- * Method outputCommentToWriter
- *
- * @param currentComment
- * @param writer writer where to write the things
- * @throws IOException
- */
- static final void outputCommentToWriter(Comment currentComment, OutputStream writer,int position) throws IOException {
- if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
- writer.write('\n');
- }
- writer.write(_BEGIN_COMM);
-
- final String data = currentComment.getData();
- final int length = data.length();
-
- for (int i = 0; i < length; i++) {
- char c=data.charAt(i);
- if (c==0x0D) {
- writer.write(__XD_);
- } else {
- if( (c & 0x80) ==0) {
- writer.write(c);
- } else {
- writeCharToUtf8(c,writer);
- };
- }
- }
-
- writer.write(_END_COMM);
- if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
- writer.write('\n');
- }
- }
-
- /**
- * Outputs a Text of CDATA section to the internal Writer.
- *
- * @param text
- * @param writer writer where to write the things
- * @throws IOException
- */
- static final void outputTextToWriter(final String text, final OutputStream writer) throws IOException {
- final int length = text.length();
- byte []toWrite;
- for (int i = 0; i < length; i++) {
- char c = text.charAt(i);
-
- switch (c) {
-
- case '&' :
- toWrite=_AMP_;
- break;
-
- case '<' :
- toWrite=_LT_;
- break;
-
- case '>' :
- toWrite=_GT_;
- break;
-
- case 0xD :
- toWrite=__XD_;
- break;
-
- default :
- if ((c & 0x80) ==0) {
- writer.write(c);
- } else {
- writeCharToUtf8(c,writer);
- };
- continue;
- }
- writer.write(toWrite);
- }
- }
-
- /**
* Obtain the attributes to output for this node in XPathNodeSet c14n.
*
* @param E
@@ -943,13 +635,206 @@
throws CanonicalizationException;
abstract void circumventBugIfNeeded(XMLSignatureInput input) throws CanonicalizationException, ParserConfigurationException, IOException, SAXException;
+
+ /**
+ * Outputs an Attribute to the internal Writer.
+ *
+ * The string value of the node is modified by replacing
+ * <UL>
+ * <LI>all ampersands (&) with <CODE>&amp;</CODE></LI>
+ * <LI>all open angle brackets (<) with <CODE>&lt;</CODE></LI>
+ * <LI>all quotation mark characters with <CODE>&quot;</CODE></LI>
+ * <LI>and the whitespace characters <CODE>#x9</CODE>, #xA, and #xD, with character
+ * references. The character references are written in uppercase
+ * hexadecimal with no leading zeroes (for example, <CODE>#xD</CODE> is represented
+ * by the character reference <CODE>&#xD;</CODE>)</LI>
+ * </UL>
+ *
+ * @param name
+ * @param value
+ * @param writer
+ * @throws IOException
+ */
+ static final void outputAttrToWriter(final String name, final String value, final OutputStream writer,
+ final Map cache) throws IOException {
+ writer.write(' ');
+ UtfHelpper.writeByte(name,writer,cache);
+ writer.write(equalsStr);
+ byte []toWrite;
+ final int length = value.length();
+ int i=0;
+ while (i < length) {
+ char c = value.charAt(i++);
+
+ switch (c) {
+
+ case '&' :
+ toWrite=_AMP_;
+ break;
+
+ case '<' :
+ toWrite=_LT_;
+ break;
+
+ case '"' :
+ toWrite=_QUOT_;
+ break;
+
+ case 0x09 : // '\t'
+ toWrite=__X9_;
+ break;
+
+ case 0x0A : // '\n'
+ toWrite=__XA_;
+ break;
+
+ case 0x0D : // '\r'
+ toWrite=__XD_;
+ break;
+
+ default :
+ if( (c & 0x80) ==0) {
+ writer.write(c);
+ } else {
+ UtfHelpper.writeCharToUtf8(c,writer);
+ };
+ continue;
+ }
+ writer.write(toWrite);
+ }
+
+ writer.write('\"');
+ }
-
- /**
- * @param _writer The _writer to set.
- */
- public void setWriter(OutputStream _writer) {
- this._writer = _writer;
- }
+ /**
+ * Outputs a PI to the internal Writer.
+ *
+ * @param currentPI
+ * @param writer where to write the things
+ * @throws IOException
+ */
+ static final void outputPItoWriter(ProcessingInstruction currentPI, OutputStream writer,int position) throws IOException {
+
+ if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
+ writer.write('\n');
+ }
+ writer.write(_BEGIN_PI);
+
+ final String target = currentPI.getTarget();
+ int length = target.length();
+
+ for (int i = 0; i < length; i++) {
+ char c=target.charAt(i);
+ if (c==0x0D) {
+ writer.write(__XD_);
+ } else {
+ if( (c & 0x80) ==0) {
+ writer.write(c);
+ } else {
+ UtfHelpper.writeCharToUtf8(c,writer);
+ };
+ }
+ }
+
+ final String data = currentPI.getData();
+
+ length = data.length();
+
+ if (length > 0) {
+ writer.write(' ');
+
+ for (int i = 0; i < length; i++) {
+ char c=data.charAt(i);
+ if (c==0x0D) {
+ writer.write(__XD_);
+ } else {
+ UtfHelpper.writeCharToUtf8(c,writer);
+ }
+ }
+ }
+
+ writer.write(_END_PI);
+ if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
+ writer.write('\n');
+ }
+ }
+
+ /**
+ * Method outputCommentToWriter
+ *
+ * @param currentComment
+ * @param writer writer where to write the things
+ * @throws IOException
+ */
+ static final void outputCommentToWriter(Comment currentComment, OutputStream writer,int position) throws IOException {
+ if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
+ writer.write('\n');
+ }
+ writer.write(_BEGIN_COMM);
+
+ final String data = currentComment.getData();
+ final int length = data.length();
+
+ for (int i = 0; i < length; i++) {
+ char c=data.charAt(i);
+ if (c==0x0D) {
+ writer.write(__XD_);
+ } else {
+ if( (c & 0x80) ==0) {
+ writer.write(c);
+ } else {
+ UtfHelpper.writeCharToUtf8(c,writer);
+ };
+ }
+ }
+
+ writer.write(_END_COMM);
+ if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
+ writer.write('\n');
+ }
+ }
+
+ /**
+ * Outputs a Text of CDATA section to the internal Writer.
+ *
+ * @param text
+ * @param writer writer where to write the things
+ * @throws IOException
+ */
+ static final void outputTextToWriter(final String text, final OutputStream writer) throws IOException {
+ final int length = text.length();
+ byte []toWrite;
+ for (int i = 0; i < length; i++) {
+ char c = text.charAt(i);
+
+ switch (c) {
+
+ case '&' :
+ toWrite=_AMP_;
+ break;
+
+ case '<' :
+ toWrite=_LT_;
+ break;
+
+ case '>' :
+ toWrite=_GT_;
+ break;
+
+ case 0xD :
+ toWrite=__XD_;
+ break;
+
+ default :
+ if ((c & 0x80) ==0) {
+ writer.write(c);
+ } else {
+ UtfHelpper.writeCharToUtf8(c,writer);
+ };
+ continue;
+ }
+ writer.write(toWrite);
+ }
+ }
}
Added: xml/security/trunk/src/org/apache/xml/security/c14n/implementations/UtfHelpper.java
URL: http://svn.apache.org/viewvc/xml/security/trunk/src/org/apache/xml/security/c14n/implementations/UtfHelpper.java?rev=429012&view=auto
==============================================================================
--- xml/security/trunk/src/org/apache/xml/security/c14n/implementations/UtfHelpper.java (added)
+++ xml/security/trunk/src/org/apache/xml/security/c14n/implementations/UtfHelpper.java Sat Aug 5 09:58:30 2006
@@ -0,0 +1,133 @@
+package org.apache.xml.security.c14n.implementations;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class UtfHelpper {
+
+ final static void writeByte(final String str,final OutputStream out,Map cache) throws IOException {
+ byte []result=(byte[]) cache.get(str);
+ if (result==null) {
+ result=getStringInUtf8(str);
+ cache.put(str,result);
+ }
+
+ out.write(result);
+
+ }
+
+ final static void writeCharToUtf8(final char c,final OutputStream out) throws IOException{
+ if ( (c & 0x80) ==0) {
+ out.write(c);
+ return;
+ }
+ int bias;
+ int write;
+ char ch;
+ if (c > 0x07FF) {
+ ch=(char)(c>>>12);
+ write=0xE0;
+ if (ch>0) {
+ write |= ( ch & 0x0F);
+ }
+ out.write(write);
+ write=0x80;
+ bias=0x3F;
+ } else {
+ write=0xC0;
+ bias=0x1F;
+ }
+ ch=(char)(c>>>6);
+ if (ch>0) {
+ write|= (ch & bias);
+ }
+ out.write(write);
+ out.write(0x80 | ((c) & 0x3F));
+
+ }
+
+ final static void writeStringToUtf8(final String str,final OutputStream out) throws IOException{
+ final int length=str.length();
+ int i=0;
+ char c;
+ while (i<length) {
+ c=str.charAt(i++);
+ if ((c & 0x80) == 0) {
+ out.write(c);
+ continue;
+ }
+ char ch;
+ int bias;
+ int write;
+ if (c > 0x07FF) {
+ ch=(char)(c>>>12);
+ write=0xE0;
+ if (ch>0) {
+ write |= ( ch & 0x0F);
+ }
+ out.write(write);
+ write=0x80;
+ bias=0x3F;
+ } else {
+ write=0xC0;
+ bias=0x1F;
+ }
+ ch=(char)(c>>>6);
+ if (ch>0) {
+ write|= (ch & bias);
+ }
+ out.write(write);
+ out.write(0x80 | ((c) & 0x3F));
+
+ }
+
+ }
+
+ public final static byte[] getStringInUtf8(final String str) {
+ final int length=str.length();
+ byte []result=new byte[length*3];
+ int i=0;
+ int out=0;
+ char c;
+ while (i<length) {
+ c=str.charAt(i++);
+ if ((c & 0x80) == 0) {
+ result[out++]=(byte)c;
+ continue;
+ }
+ char ch;
+ int bias;
+ byte write;
+ if (c > 0x07FF) {
+ ch=(char)(c>>>12);
+ write=(byte)0xE0;
+ if (ch>0) {
+ write |= ( ch & 0x0F);
+ }
+ result[out++]=write;
+ write=(byte)0x80;
+ bias=0x3F;
+ } else {
+ write=(byte)0xC0;
+ bias=0x1F;
+ }
+ ch=(char)(c>>>6);
+ if (ch>0) {
+ write|= (ch & bias);
+ }
+ result[out++]=write;
+ result[out++]=(byte)(0x80 | ((c) & 0x3F));
+
+ }
+ byte newResult[]=new byte[out];
+ System.arraycopy(result, 0, newResult, 0, out);
+ return newResult;
+ }
+
+
+
+}