geuerp 2002/09/08 04:55:24
Modified: src/org/apache/xml/security/c14n/implementations
Canonicalizer20010315.java
Canonicalizer20010315Excl.java
Canonicalizer20010315ExclWithComments.java
Added: src/org/apache/xml/security/c14n/implementations
CanonicalizerBase.java
Log:
First refactoring which moves common stuff to CanonicalizerBase
Revision Changes Path
1.27 +4 -563
xml-security/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315.java
Index: Canonicalizer20010315.java
===================================================================
RCS file:
/home/cvs/xml-security/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- Canonicalizer20010315.java 4 Sep 2002 15:07:55 -0000 1.26
+++ Canonicalizer20010315.java 8 Sep 2002 11:55:24 -0000 1.27
@@ -80,18 +80,7 @@
* @author Christian Geuer-Pollmann <[EMAIL PROTECTED]>
* @version $Revision$
*/
-public abstract class Canonicalizer20010315 extends CanonicalizerSpi {
- //J-
- boolean _includeComments = false;
-
- Set _xpathNodeSet = null;
-
- Document _doc = null;
- Element _documentElement = null;
- Node _rootNodeOfC14n = null;
-
- Writer _writer = null;
- //J+
+public abstract class Canonicalizer20010315 extends CanonicalizerBase {
/**
* Constructor Canonicalizer20010315
@@ -99,149 +88,7 @@
* @param includeComments
*/
public Canonicalizer20010315(boolean includeComments) {
- this._includeComments = includeComments;
- }
-
- /**
- * Method engineCanonicalizeSubTree
- *
- * @param rootNode
- * @throws CanonicalizationException
- */
- public byte[] engineCanonicalizeSubTree(Node rootNode)
- throws CanonicalizationException {
-
- this._rootNodeOfC14n = rootNode;
- this._doc = XMLUtils.getOwnerDocument(this._rootNodeOfC14n);
- this._documentElement = this._doc.getDocumentElement();
-
- XMLUtils.circumventBug2650(this._doc);
-
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- this._writer = new OutputStreamWriter(baos, Canonicalizer.ENCODING);
-
- this.canonicalizeSubTree(this._rootNodeOfC14n, true);
- this._writer.close();
-
- return baos.toByteArray();
- } catch (UnsupportedEncodingException ex) {
- throw new CanonicalizationException("empty", ex);
- } catch (IOException ex) {
- throw new CanonicalizationException("empty", ex);
- } finally {
-
- // mark contents for garbage collector
- this._rootNodeOfC14n = null;
- this._doc = null;
- this._documentElement = null;
- this._writer = null;
- }
- }
-
- /**
- * Method canonicalizeSubTree
- *
- * @param currentNode
- * @throws CanonicalizationException
- * @throws IOException
- */
- void canonicalizeSubTree(Node currentNode, boolean isRootNode)
- throws CanonicalizationException, IOException {
-
- int currentNodeType = currentNode.getNodeType();
-
- switch (currentNodeType) {
-
- case Node.DOCUMENT_TYPE_NODE :
- default :
- break;
-
- case Node.ENTITY_NODE :
- case Node.NOTATION_NODE :
- case Node.DOCUMENT_FRAGMENT_NODE :
- case Node.ATTRIBUTE_NODE :
-
- // illegal node type during traversal
- throw new CanonicalizationException("empty");
- case Node.DOCUMENT_NODE :
- for (Node currentChild = currentNode.getFirstChild();
- currentChild != null;
- currentChild = currentChild.getNextSibling()) {
- canonicalizeSubTree(currentChild, false);
- }
- break;
-
- case Node.COMMENT_NODE :
- if (this._includeComments) {
- int position =
- Canonicalizer20010315.getPositionRelativeToDocumentElement(
- currentNode);
-
- if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
-
- this.outputCommentToWriter((Comment) currentNode);
-
- if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
- }
- break;
-
- case Node.PROCESSING_INSTRUCTION_NODE :
- int position =
- Canonicalizer20010315.getPositionRelativeToDocumentElement(
- currentNode);
-
- if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
-
- this.outputPItoWriter((ProcessingInstruction) currentNode);
-
- if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
- break;
-
- case Node.TEXT_NODE :
- case Node.CDATA_SECTION_NODE :
- this.outputTextToWriter(currentNode.getNodeValue());
- break;
-
- case Node.ELEMENT_NODE :
- Element currentElement = (Element) currentNode;
-
- this._writer.write("<");
- this._writer.write(currentElement.getTagName());
-
- Object[] attrs = this.handleAttributesSubtree(currentElement);
-
- attrs = C14nHelper.sortAttributes(attrs);
-
- // we output all Attrs which are available
- for (int i = 0; i < attrs.length; i++) {
- this.outputAttrToWriter(((Attr) attrs[i]).getNodeName(),
- ((Attr) attrs[i]).getNodeValue());
- }
-
- this._writer.write(">");
-
- // traversal
- for (Node currentChild = currentNode.getFirstChild();
- currentChild != null;
- currentChild = currentChild.getNextSibling()) {
- canonicalizeSubTree(currentChild, false);
- }
-
- this._writer.write("</");
- this._writer.write(currentElement.getTagName());
- this._writer.write(">");
- break;
- }
+ super(includeComments);
}
/**
@@ -457,226 +304,7 @@
}
}
- return result.toArray();
- }
-
- //J-
- private static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
- private static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
- private static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
- //J+
-
- /**
- * Checks whether a Comment or ProcessingInstruction is before or after
the
- * document element. This is needed for prepending or appending "\n"s.
- *
- * @param currentNode comment or pi to check
- * @return NODE_BEFORE_DOCUMENT_ELEMENT,
NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT or NODE_AFTER_DOCUMENT_ELEMENT
- * @see NODE_BEFORE_DOCUMENT_ELEMENT
- * @see NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT
- * @see NODE_AFTER_DOCUMENT_ELEMENT
- */
- static int getPositionRelativeToDocumentElement(Node currentNode) {
-
- if (currentNode == null) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- Document doc = currentNode.getOwnerDocument();
-
- if (currentNode.getParentNode() != doc) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- Element documentElement = doc.getDocumentElement();
-
- if (documentElement == null) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- if (documentElement == currentNode) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- for (Node x = currentNode; x != null; x = x.getNextSibling()) {
- if (x == documentElement) {
- return NODE_BEFORE_DOCUMENT_ELEMENT;
- }
- }
-
- return NODE_AFTER_DOCUMENT_ELEMENT;
- }
-
- /**
- * Method engineCanonicalizeXPathNodeSet
- *
- * @param xpathNodeSet
- * @throws CanonicalizationException
- */
- public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet)
- throws CanonicalizationException {
-
- this._xpathNodeSet = xpathNodeSet;
-
- if (this._xpathNodeSet.size() == 0) {
- return new byte[0];
- }
-
- if (this._doc == null) {
- Node n = (Node) this._xpathNodeSet.iterator().next();
-
- this._doc = XMLUtils.getOwnerDocument(n);
- this._documentElement = this._doc.getDocumentElement();
- this._rootNodeOfC14n = this._doc;
- }
-
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- this._writer = new OutputStreamWriter(baos, Canonicalizer.ENCODING);
-
- this.canonicalizeXPathNodeSet(this._rootNodeOfC14n);
- this._writer.close();
-
- return baos.toByteArray();
- } catch (UnsupportedEncodingException ex) {
- throw new CanonicalizationException("empty", ex);
- } catch (IOException ex) {
- throw new CanonicalizationException("empty", ex);
- } finally {
- this._xpathNodeSet = null;
- this._rootNodeOfC14n = null;
- this._doc = null;
- this._documentElement = null;
- this._writer = null;
- }
- }
-
- /**
- * Method canonicalizeXPathNodeSet
- *
- * @param currentNode
- * @throws CanonicalizationException
- * @throws IOException
- */
- void canonicalizeXPathNodeSet(Node currentNode)
- throws CanonicalizationException, IOException {
-
- int currentNodeType = currentNode.getNodeType();
- boolean currentNodeIsVisible =
this._xpathNodeSet.contains(currentNode);
-
- switch (currentNodeType) {
-
- case Node.DOCUMENT_TYPE_NODE :
- default :
- break;
-
- case Node.ENTITY_NODE :
- case Node.NOTATION_NODE :
- case Node.DOCUMENT_FRAGMENT_NODE :
- case Node.ATTRIBUTE_NODE :
- throw new CanonicalizationException("empty");
- case Node.DOCUMENT_NODE :
- for (Node currentChild = currentNode.getFirstChild();
- currentChild != null;
- currentChild = currentChild.getNextSibling()) {
- canonicalizeXPathNodeSet(currentChild);
- }
- break;
-
- case Node.COMMENT_NODE :
- if (this._includeComments
- && this._xpathNodeSet.contains(currentNode)) {
- int position = getPositionRelativeToDocumentElement(currentNode);
-
- if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
-
- this.outputCommentToWriter((Comment) currentNode);
-
- if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
- }
- break;
-
- case Node.PROCESSING_INSTRUCTION_NODE :
- if (this._xpathNodeSet.contains(currentNode)) {
- int position = getPositionRelativeToDocumentElement(currentNode);
-
- if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
-
- this.outputPItoWriter((ProcessingInstruction) currentNode);
-
- if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
- this._writer.write("\n");
- }
- }
- break;
-
- case Node.TEXT_NODE :
- case Node.CDATA_SECTION_NODE :
- if (this._xpathNodeSet.contains(currentNode)) {
- this.outputTextToWriter(currentNode.getNodeValue());
-
- for (Node nextSibling = currentNode.getNextSibling();
- (nextSibling != null)
- && ((nextSibling.getNodeType() == Node.TEXT_NODE)
- || (nextSibling.getNodeType()
- == Node.CDATA_SECTION_NODE));
- nextSibling = nextSibling.getNextSibling()) {
-
- /* The XPath data model allows to select only the first of a
- * sequence of mixed text and CDATA nodes. But we must output
- * them all, so we must search:
- *
- * @see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6329
- */
- this.outputTextToWriter(nextSibling.getNodeValue());
- }
- }
- break;
-
- case Node.ELEMENT_NODE :
- Element currentElement = (Element) currentNode;
-
- if (currentNodeIsVisible) {
- this._writer.write("<");
- this._writer.write(currentElement.getTagName());
- }
-
- // we output all Attrs which are available
- Object[] attrs = handleAttributes(currentElement);
-
- attrs = C14nHelper.sortAttributes(attrs);
-
- for (int i = 0; i < attrs.length; i++) {
- Attr attr = (Attr) attrs[i];
-
- this.outputAttrToWriter(attr.getNodeName(), attr.getNodeValue());
- }
-
- if (currentNodeIsVisible) {
- this._writer.write(">");
- }
-
- // traversal
- for (Node currentChild = currentNode.getFirstChild();
- currentChild != null;
- currentChild = currentChild.getNextSibling()) {
- canonicalizeXPathNodeSet(currentChild);
- }
-
- if (currentNodeIsVisible) {
- this._writer.write("</");
- this._writer.write(currentElement.getTagName());
- this._writer.write(">");
- }
- break;
- }
+ return C14nHelper.sortAttributes(result.toArray());
}
/**
@@ -920,193 +548,6 @@
}
return result.toArray();
- }
-
- /**
- * Normalizes an [EMAIL PROTECTED] Attr}ibute value
- *
- * 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
- * @throws IOException
- */
- void outputAttrToWriter(String name, String value) throws IOException {
-
- this._writer.write(" ");
- this._writer.write(name);
- this._writer.write("=\"");
-
- int length = value.length();
-
- for (int i = 0; i < length; i++) {
- char c = value.charAt(i);
-
- switch (c) {
-
- case '&' :
- this._writer.write("&");
- break;
-
- case '<' :
- this._writer.write("<");
- break;
-
- case '"' :
- this._writer.write(""");
- break;
-
- case 0x09 : // '\t'
- this._writer.write("	");
- break;
-
- case 0x0A : // '\n'
- this._writer.write("
");
- break;
-
- case 0x0D : // '\r'
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
-
- this._writer.write("\"");
- }
-
- /**
- * Normalizes a [EMAIL PROTECTED] org.w3c.dom.Comment} value
- *
- * @param currentPI
- * @throws IOException
- */
- void outputPItoWriter(ProcessingInstruction currentPI) throws IOException
{
-
- this._writer.write("<?");
-
- String target = currentPI.getTarget();
- int length = target.length();
-
- for (int i = 0; i < length; i++) {
- char c = target.charAt(i);
-
- switch (c) {
-
- case 0x0D :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
-
- String data = currentPI.getData();
-
- length = data.length();
-
- if ((data != null) && (length > 0)) {
- this._writer.write(" ");
-
- for (int i = 0; i < length; i++) {
- char c = data.charAt(i);
-
- switch (c) {
-
- case 0x0D :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
- }
-
- this._writer.write("?>");
- }
-
- /**
- * Method outputCommentToWriter
- *
- * @param currentComment
- * @throws IOException
- */
- void outputCommentToWriter(Comment currentComment) throws IOException {
-
- this._writer.write("<!--");
-
- String data = currentComment.getData();
- int length = data.length();
-
- for (int i = 0; i < length; i++) {
- char c = data.charAt(i);
-
- switch (c) {
-
- case 0x0D :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
-
- this._writer.write("-->");
- }
-
- /**
- * Method outputTextToWriter
- *
- * @param text
- * @throws IOException
- */
- void outputTextToWriter(String text) throws IOException {
-
- int length = text.length();
-
- for (int i = 0; i < length; i++) {
- char c = text.charAt(i);
-
- switch (c) {
-
- case '&' :
- this._writer.write("&");
- break;
-
- case '<' :
- this._writer.write("<");
- break;
-
- case '>' :
- this._writer.write(">");
- break;
-
- case 0xD :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
}
/**
1.8 +149 -433
xml-security/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315Excl.java
Index: Canonicalizer20010315Excl.java
===================================================================
RCS file:
/home/cvs/xml-security/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315Excl.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Canonicalizer20010315Excl.java 4 Sep 2002 15:07:55 -0000 1.7
+++ Canonicalizer20010315Excl.java 8 Sep 2002 11:55:24 -0000 1.8
@@ -91,24 +91,7 @@
* @version $Revision$
* @see <A
HREF="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">"Exclusive XML
Canonicalization, Version 1.0"</A>
*/
-public abstract class Canonicalizer20010315Excl extends CanonicalizerSpi {
- //J-
- boolean _includeComments = false;
-
- Set _xpathNodeSet = null;
-
- /**
- * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of
- * the inclusive namespaces.
- */
- Set _inclusiveNSSet = null;
-
- Document _doc = null;
- Element _documentElement = null;
- Node _rootNodeOfC14n = null;
- HashMap _renderedPrefixesForElement = null;
- Writer _writer = null;
- //J+
+public abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
/**
* Constructor Canonicalizer20010315Excl
@@ -116,7 +99,7 @@
* @param includeComments
*/
public Canonicalizer20010315Excl(boolean includeComments) {
- this._includeComments = includeComments;
+ super(includeComments);
}
/**
@@ -400,100 +383,20 @@
}
/**
- * Collects all relevant xml:* and attributes from all ancestor
- * Elements from rootNode and creates a Map containg the attribute
- * names/values.
- *
- * @param apexNode
+ * Method handleAttributesSubtree
*
+ * @param E
* @throws CanonicalizationException
*/
- Map getInscopeNamespaces(Node apexNode) throws CanonicalizationException {
-
- Map result = new HashMap();
-
- if (apexNode.getNodeType() != Node.ELEMENT_NODE) {
- return result;
- }
-
- Element apexElement = (Element) apexNode;
-
- for (Node parent = apexElement.getParentNode();
- ((parent != null) && (parent.getNodeType() ==
Node.ELEMENT_NODE));
- parent = parent.getParentNode()) {
- NamedNodeMap attributes = parent.getAttributes();
- int nrOfAttrs = attributes.getLength();
-
- for (int i = 0; i < nrOfAttrs; i++) {
- Attr currentAttr = (Attr) attributes.item(i);
- String name = currentAttr.getNodeName();
- String value = currentAttr.getValue();
-
- if (name.equals("xmlns") && value.equals("")) {
- result.remove(name);
- } else if (name.startsWith("xmlns") &&!value.equals("")) {
- if (!result.containsKey(name)) {
- result.put(name, value);
- }
- }
- }
- }
-
- return result;
- }
-
- //J-
- private static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
- private static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
- private static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
- //J+
-
- /**
- * Checks whether a Comment or ProcessingInstruction is before or after
the
- * document element. This is needed for prepending or appending "\n"s.
- *
- * @param currentNode comment or pi to check
- * @return NODE_BEFORE_DOCUMENT_ELEMENT,
NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT or NODE_AFTER_DOCUMENT_ELEMENT
- * @see NODE_BEFORE_DOCUMENT_ELEMENT
- * @see NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT
- * @see NODE_AFTER_DOCUMENT_ELEMENT
- */
- static int getPositionRelativeToDocumentElement(Node currentNode) {
-
- if (currentNode == null) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- Document doc = currentNode.getOwnerDocument();
-
- if (currentNode.getParentNode() != doc) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- Element documentElement = doc.getDocumentElement();
-
- if (documentElement == null) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- if (documentElement == currentNode) {
- return NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
- }
-
- for (Node x = currentNode; x != null; x = x.getNextSibling()) {
- if (x == documentElement) {
- return NODE_BEFORE_DOCUMENT_ELEMENT;
- }
- }
-
- return NODE_AFTER_DOCUMENT_ELEMENT;
+ Object[] handleAttributesSubtree(Element E)
+ throws CanonicalizationException {
+ throw new RuntimeException("Not yet implemented");
}
/**
* Method engineCanonicalizeXPathNodeSet
*
* @param xpathNodeSet
- *
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet)
@@ -506,51 +409,20 @@
*
* @param xpathNodeSet
* @param inclusiveNamespaces
- *
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet, String
inclusiveNamespaces)
throws CanonicalizationException {
- this._xpathNodeSet = xpathNodeSet;
-
- if (this._xpathNodeSet.size() == 0) {
- return new byte[0];
- }
-
- {
-
- // get only a single node as anchor to fetch the owner document
- Node n = (Node) this._xpathNodeSet.iterator().next();
-
- this._doc = XMLUtils.getOwnerDocument(n);
- this._documentElement = this._doc.getDocumentElement();
- }
-
try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
- this._writer = new OutputStreamWriter(baos, Canonicalizer.ENCODING);
this._inclusiveNSSet =
InclusiveNamespaces.prefixStr2Set(inclusiveNamespaces);
this._renderedPrefixesForElement = new HashMap();
- this.canonicalizeXPathNodeSet(this._doc);
- this._writer.close();
-
- return baos.toByteArray();
- } catch (UnsupportedEncodingException ex) {
- throw new CanonicalizationException("empty", ex);
- } catch (IOException ex) {
- throw new CanonicalizationException("empty", ex);
+ return super.engineCanonicalizeXPathNodeSet(xpathNodeSet);
} finally {
- this._xpathNodeSet = null;
this._inclusiveNSSet = null;
- this._rootNodeOfC14n = null;
- this._doc = null;
- this._documentElement = null;
this._renderedPrefixesForElement = null;
- this._writer = null;
}
}
@@ -684,302 +556,6 @@
}
/**
- * Normalizes an [EMAIL PROTECTED] Attr}ibute value
- *
- * 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
- * @throws IOException
- */
- void outputAttrToWriter(String name, String value) throws IOException {
-
- this._writer.write(" ");
- this._writer.write(name);
- this._writer.write("=\"");
-
- int length = value.length();
-
- for (int i = 0; i < length; i++) {
- char c = value.charAt(i);
-
- switch (c) {
-
- case '&' :
- this._writer.write("&");
- break;
-
- case '<' :
- this._writer.write("<");
- break;
-
- case '"' :
- this._writer.write(""");
- break;
-
- case 0x09 : // '\t'
- this._writer.write("	");
- break;
-
- case 0x0A : // '\n'
- this._writer.write("
");
- break;
-
- case 0x0D : // '\r'
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
-
- this._writer.write("\"");
- }
-
- /**
- * Normalizes a [EMAIL PROTECTED] org.w3c.dom.Comment} value
- *
- * @param currentPI
- * @throws IOException
- */
- void outputPItoWriter(ProcessingInstruction currentPI) throws IOException
{
-
- if (currentPI == null) {
- return;
- }
-
- this._writer.write("<?");
-
- String target = currentPI.getTarget();
- int length = target.length();
-
- for (int i = 0; i < length; i++) {
- char c = target.charAt(i);
-
- switch (c) {
-
- case 0x0D :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
-
- String data = currentPI.getData();
-
- length = data.length();
-
- if ((data != null) && (length > 0)) {
- this._writer.write(" ");
-
- for (int i = 0; i < length; i++) {
- char c = data.charAt(i);
-
- switch (c) {
-
- case 0x0D :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
- }
-
- this._writer.write("?>");
- }
-
- /**
- * Method outputCommentToWriter
- *
- * @param currentComment
- * @throws IOException
- */
- void outputCommentToWriter(Comment currentComment) throws IOException {
-
- if (currentComment == null) {
- return;
- }
-
- this._writer.write("<!--");
-
- String data = currentComment.getData();
- int length = data.length();
-
- for (int i = 0; i < length; i++) {
- char c = data.charAt(i);
-
- switch (c) {
-
- case 0x0D :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
-
- this._writer.write("-->");
- }
-
- /**
- * Method outputTextToWriter
- *
- * @param text
- * @throws IOException
- */
- void outputTextToWriter(String text) throws IOException {
-
- if (text == null) {
- return;
- }
-
- int length = text.length();
-
- for (int i = 0; i < length; i++) {
- char c = text.charAt(i);
-
- switch (c) {
-
- case '&' :
- this._writer.write("&");
- break;
-
- case '<' :
- this._writer.write("<");
- break;
-
- case '>' :
- this._writer.write(">");
- break;
-
- case 0xD :
- this._writer.write("
");
- break;
-
- default :
- this._writer.write(c);
- break;
- }
- }
- }
-
- /**
- * Returns <code>true</code> is the namespace is either utilized by the
- * given element or included by the includedNamespaces parameter.
- *
- * @param element
- * @param namespace
- *
- */
- public boolean utilizedOrIncluded(Element element, String namespace) {
-
- if (this._inclusiveNSSet.contains(namespace)) {
-
- // included;
- return true;
- }
-
- boolean utilized = this.visiblyUtilized(element).contains(namespace);
-
- return utilized;
- }
-
- /**
- * Method visiblyUtilized
- *
- * @param element
- * @return a Set of namespace names.
- */
- public Set visiblyUtilized(Element element) {
-
- Set result = new HashSet();
-
- if (this._xpathNodeSet == null) {
-
- // we are in the canonicalizeSubtree part
- if (element.getNamespaceURI() != null) {
- String prefix = element.getPrefix();
-
- if (prefix == null) {
- result.add("xmlns");
- } else {
- result.add("xmlns:" + prefix);
- }
- }
-
- NamedNodeMap attributes = element.getAttributes();
- int attributesLength = attributes.getLength();
-
- // if the attribute is not xmlns:... and not xml:... but
- // a:..., add xmlns:a to the list
- for (int i = 0; i < attributesLength; i++) {
- Attr currentAttr = (Attr) attributes.item(i);
- String prefix = currentAttr.getPrefix();
-
- if (prefix != null) {
- if (!prefix.equals("xml") &&!prefix.equals("xmlns")) {
- result.add("xmlns:" + prefix);
- }
- }
- }
- } else {
- if (this._xpathNodeSet.contains(element)) {
-
- // we are in the canonicalizeXPathNodeSet part
- if (element.getNamespaceURI() != null) {
- String prefix = element.getPrefix();
-
- if ((prefix == null) || (prefix.length() == 0)) {
- result.add("xmlns");
- } else {
- result.add("xmlns:" + prefix);
- }
- }
-
- NamedNodeMap attributes = element.getAttributes();
- int attributesLength = attributes.getLength();
-
- // if the attribute is not xmlns:... and not xml:... but
- // a:..., add xmlns:a to the list
- for (int i = 0; i < attributesLength; i++) {
- Attr currentAttr = (Attr) attributes.item(i);
-
- if (this._xpathNodeSet.contains(currentAttr)) {
- String prefix = currentAttr.getPrefix();
-
- if (prefix != null) {
- if (!prefix.equals("xml") &&!prefix.equals("xmlns")) {
- result.add("xmlns:" + prefix);
- }
- }
- }
- }
- }
- }
-
- return result;
- }
-
- /**
*
* @param E
* @throws CanonicalizationException
@@ -1499,5 +1075,145 @@
Object sortedResultAsArray[] =
C14nHelper.sortAttributes(resultAsArray);
return sortedResultAsArray;
+ }
+
+ /**
+ * Collects all relevant xml:* and attributes from all ancestor
+ * Elements from rootNode and creates a Map containg the attribute
+ * names/values.
+ *
+ * @param apexNode
+ *
+ * @throws CanonicalizationException
+ */
+ Map getInscopeNamespaces(Node apexNode) throws CanonicalizationException {
+
+ Map result = new HashMap();
+
+ if (apexNode.getNodeType() != Node.ELEMENT_NODE) {
+ return result;
+ }
+
+ Element apexElement = (Element) apexNode;
+
+ for (Node parent = apexElement.getParentNode();
+ ((parent != null) && (parent.getNodeType() ==
Node.ELEMENT_NODE));
+ parent = parent.getParentNode()) {
+ NamedNodeMap attributes = parent.getAttributes();
+ int nrOfAttrs = attributes.getLength();
+
+ for (int i = 0; i < nrOfAttrs; i++) {
+ Attr currentAttr = (Attr) attributes.item(i);
+ String name = currentAttr.getNodeName();
+ String value = currentAttr.getValue();
+
+ if (name.equals("xmlns") && value.equals("")) {
+ result.remove(name);
+ } else if (name.startsWith("xmlns") &&!value.equals("")) {
+ if (!result.containsKey(name)) {
+ result.put(name, value);
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns <code>true</code> is the namespace is either utilized by the
+ * given element or included by the includedNamespaces parameter.
+ *
+ * @param element
+ * @param namespace
+ *
+ */
+ public boolean utilizedOrIncluded(Element element, String namespace) {
+
+ if (this._inclusiveNSSet.contains(namespace)) {
+
+ // included;
+ return true;
+ }
+
+ boolean utilized = this.visiblyUtilized(element).contains(namespace);
+
+ return utilized;
+ }
+
+ /**
+ * Method visiblyUtilized
+ *
+ * @param element
+ * @return a Set of namespace names.
+ */
+ public Set visiblyUtilized(Element element) {
+
+ Set result = new HashSet();
+
+ if (this._xpathNodeSet == null) {
+
+ // we are in the canonicalizeSubtree part
+ if (element.getNamespaceURI() != null) {
+ String prefix = element.getPrefix();
+
+ if (prefix == null) {
+ result.add("xmlns");
+ } else {
+ result.add("xmlns:" + prefix);
+ }
+ }
+
+ NamedNodeMap attributes = element.getAttributes();
+ int attributesLength = attributes.getLength();
+
+ // if the attribute is not xmlns:... and not xml:... but
+ // a:..., add xmlns:a to the list
+ for (int i = 0; i < attributesLength; i++) {
+ Attr currentAttr = (Attr) attributes.item(i);
+ String prefix = currentAttr.getPrefix();
+
+ if (prefix != null) {
+ if (!prefix.equals("xml") &&!prefix.equals("xmlns")) {
+ result.add("xmlns:" + prefix);
+ }
+ }
+ }
+ } else {
+ if (this._xpathNodeSet.contains(element)) {
+
+ // we are in the canonicalizeXPathNodeSet part
+ if (element.getNamespaceURI() != null) {
+ String prefix = element.getPrefix();
+
+ if ((prefix == null) || (prefix.length() == 0)) {
+ result.add("xmlns");
+ } else {
+ result.add("xmlns:" + prefix);
+ }
+ }
+
+ NamedNodeMap attributes = element.getAttributes();
+ int attributesLength = attributes.getLength();
+
+ // if the attribute is not xmlns:... and not xml:... but
+ // a:..., add xmlns:a to the list
+ for (int i = 0; i < attributesLength; i++) {
+ Attr currentAttr = (Attr) attributes.item(i);
+
+ if (this._xpathNodeSet.contains(currentAttr)) {
+ String prefix = currentAttr.getPrefix();
+
+ if (prefix != null) {
+ if (!prefix.equals("xml") &&!prefix.equals("xmlns")) {
+ result.add("xmlns:" + prefix);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return result;
}
}
1.3 +1 -2
xml-security/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java
Index: Canonicalizer20010315ExclWithComments.java
===================================================================
RCS file:
/home/cvs/xml-security/src/org/apache/xml/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Canonicalizer20010315ExclWithComments.java 28 Aug 2002 12:08:24
-0000 1.2
+++ Canonicalizer20010315ExclWithComments.java 8 Sep 2002 11:55:24
-0000 1.3
@@ -66,7 +66,6 @@
/**
* Class Canonicalizer20010315ExclWithComments
*
- * @author $Author$
* @version $Revision$
*/
public class Canonicalizer20010315ExclWithComments
1.1
xml-security/src/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java
Index: CanonicalizerBase.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "<WebSig>" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2001, Institute for
* Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>.
* The development of this software was partly funded by the European
* Commission in the <WebSig> project in the ISIS Programme.
* For more information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.xml.security.c14n.implementations;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.TransformerException;
import org.apache.xml.security.c14n.*;
import org.apache.xml.security.c14n.helper.*;
import org.apache.xml.security.utils.*;
import org.apache.xpath.CachedXPathAPI;
import org.w3c.dom.*;
import org.xml.sax.*;
/**
* Abstract base class for canonicalization algorithms.
*
* @author Christian Geuer-Pollmann <[EMAIL PROTECTED]>
* @version $Revision: 1.1 $
*/
public abstract class CanonicalizerBase extends CanonicalizerSpi {
//J-
boolean _includeComments = false;
Set _xpathNodeSet = null;
Document _doc = null;
Element _documentElement = null;
Node _rootNodeOfC14n = null;
Writer _writer = null;
/**
* This Set contains the names (Strings like "xmlns" or "xmlns:foo") of
* the inclusive namespaces.
*/
Set _inclusiveNSSet = null;
HashMap _renderedPrefixesForElement = null;
//J+
/**
* Constructor CanonicalizerBase
*
* @param includeComments
*/
public CanonicalizerBase(boolean includeComments) {
this._includeComments = includeComments;
}
/**
* Method engineCanonicalizeSubTree
*
* @param rootNode
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeSubTree(Node rootNode)
throws CanonicalizationException {
this._rootNodeOfC14n = rootNode;
this._doc = XMLUtils.getOwnerDocument(this._rootNodeOfC14n);
this._documentElement = this._doc.getDocumentElement();
XMLUtils.circumventBug2650(this._doc);
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
this._writer = new OutputStreamWriter(baos, Canonicalizer.ENCODING);
this.canonicalizeSubTree(this._rootNodeOfC14n);
this._writer.close();
return baos.toByteArray();
} catch (UnsupportedEncodingException ex) {
throw new CanonicalizationException("empty", ex);
} catch (IOException ex) {
throw new CanonicalizationException("empty", ex);
} finally {
// mark contents for garbage collector
this._rootNodeOfC14n = null;
this._doc = null;
this._documentElement = null;
this._writer = null;
}
}
/**
* Method canonicalizeSubTree
*
* @param currentNode
* @throws CanonicalizationException
* @throws IOException
*/
void canonicalizeSubTree(Node currentNode)
throws CanonicalizationException, IOException {
int currentNodeType = currentNode.getNodeType();
switch (currentNodeType) {
case Node.DOCUMENT_TYPE_NODE :
default :
break;
case Node.ENTITY_NODE :
case Node.NOTATION_NODE :
case Node.DOCUMENT_FRAGMENT_NODE :
case Node.ATTRIBUTE_NODE :
// illegal node type during traversal
throw new CanonicalizationException("empty");
case Node.DOCUMENT_NODE :
for (Node currentChild = currentNode.getFirstChild();
currentChild != null;
currentChild = currentChild.getNextSibling()) {
canonicalizeSubTree(currentChild);
}
break;
case Node.COMMENT_NODE :
if (this._includeComments) {
int position =
CanonicalizerBase.getPositionRelativeToDocumentElement(
currentNode);
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
this.outputCommentToWriter((Comment) currentNode);
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
}
break;
case Node.PROCESSING_INSTRUCTION_NODE :
int position =
CanonicalizerBase.getPositionRelativeToDocumentElement(currentNode);
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
this.outputPItoWriter((ProcessingInstruction) currentNode);
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
break;
case Node.TEXT_NODE :
case Node.CDATA_SECTION_NODE :
this.outputTextToWriter(currentNode.getNodeValue());
break;
case Node.ELEMENT_NODE :
Element currentElement = (Element) currentNode;
this._writer.write("<");
this._writer.write(currentElement.getTagName());
Object[] attrs = this.handleAttributesSubtree(currentElement);
// we output all Attrs which are available
for (int i = 0; i < attrs.length; i++) {
this.outputAttrToWriter(((Attr) attrs[i]).getNodeName(),
((Attr) attrs[i]).getNodeValue());
}
this._writer.write(">");
// traversal
for (Node currentChild = currentNode.getFirstChild();
currentChild != null;
currentChild = currentChild.getNextSibling()) {
canonicalizeSubTree(currentChild);
}
this._writer.write("</");
this._writer.write(currentElement.getTagName());
this._writer.write(">");
break;
}
}
//J-
static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
//J+
/**
* Checks whether a Comment or ProcessingInstruction is before or after the
* document element. This is needed for prepending or appending "\n"s.
*
* @param currentNode comment or pi to check
* @return NODE_BEFORE_DOCUMENT_ELEMENT,
NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT or NODE_AFTER_DOCUMENT_ELEMENT
* @see NODE_BEFORE_DOCUMENT_ELEMENT
* @see NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT
* @see NODE_AFTER_DOCUMENT_ELEMENT
*/
static int getPositionRelativeToDocumentElement(Node currentNode) {
if (currentNode == null) {
return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
}
Document doc = currentNode.getOwnerDocument();
if (currentNode.getParentNode() != doc) {
return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
}
Element documentElement = doc.getDocumentElement();
if (documentElement == null) {
return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
}
if (documentElement == currentNode) {
return CanonicalizerBase.NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
}
for (Node x = currentNode; x != null; x = x.getNextSibling()) {
if (x == documentElement) {
return CanonicalizerBase.NODE_BEFORE_DOCUMENT_ELEMENT;
}
}
return CanonicalizerBase.NODE_AFTER_DOCUMENT_ELEMENT;
}
/**
* Method engineCanonicalizeXPathNodeSet
*
* @param xpathNodeSet
* @param inclusiveNamespaces
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet, String
inclusiveNamespaces)
throws CanonicalizationException {
this._xpathNodeSet = xpathNodeSet;
if (this._xpathNodeSet.size() == 0) {
return new byte[0];
}
{
// get only a single node as anchor to fetch the owner document
Node n = (Node) this._xpathNodeSet.iterator().next();
this._doc = XMLUtils.getOwnerDocument(n);
this._documentElement = this._doc.getDocumentElement();
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
this._writer = new OutputStreamWriter(baos, Canonicalizer.ENCODING);
this.canonicalizeXPathNodeSet(this._doc);
this._writer.close();
return baos.toByteArray();
} catch (UnsupportedEncodingException ex) {
throw new CanonicalizationException("empty", ex);
} catch (IOException ex) {
throw new CanonicalizationException("empty", ex);
} finally {
this._xpathNodeSet = null;
this._rootNodeOfC14n = null;
this._doc = null;
this._documentElement = null;
this._writer = null;
}
}
/**
* Method engineCanonicalizeXPathNodeSet
*
* @param xpathNodeSet
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet)
throws CanonicalizationException {
this._xpathNodeSet = xpathNodeSet;
if (this._xpathNodeSet.size() == 0) {
return new byte[0];
}
if (this._doc == null) {
Node n = (Node) this._xpathNodeSet.iterator().next();
this._doc = XMLUtils.getOwnerDocument(n);
this._documentElement = this._doc.getDocumentElement();
this._rootNodeOfC14n = this._doc;
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
this._writer = new OutputStreamWriter(baos, Canonicalizer.ENCODING);
this.canonicalizeXPathNodeSet(this._rootNodeOfC14n);
this._writer.close();
return baos.toByteArray();
} catch (UnsupportedEncodingException ex) {
throw new CanonicalizationException("empty", ex);
} catch (IOException ex) {
throw new CanonicalizationException("empty", ex);
} finally {
this._xpathNodeSet = null;
this._rootNodeOfC14n = null;
this._doc = null;
this._documentElement = null;
this._writer = null;
}
}
/**
* Method canonicalizeXPathNodeSet
*
* @param currentNode
* @throws CanonicalizationException
* @throws IOException
*/
void canonicalizeXPathNodeSet(Node currentNode)
throws CanonicalizationException, IOException {
int currentNodeType = currentNode.getNodeType();
boolean currentNodeIsVisible = this._xpathNodeSet.contains(currentNode);
switch (currentNodeType) {
case Node.DOCUMENT_TYPE_NODE :
default :
break;
case Node.ENTITY_NODE :
case Node.NOTATION_NODE :
case Node.DOCUMENT_FRAGMENT_NODE :
case Node.ATTRIBUTE_NODE :
throw new CanonicalizationException("empty");
case Node.DOCUMENT_NODE :
for (Node currentChild = currentNode.getFirstChild();
currentChild != null;
currentChild = currentChild.getNextSibling()) {
canonicalizeXPathNodeSet(currentChild);
}
break;
case Node.COMMENT_NODE :
if (this._includeComments
&& this._xpathNodeSet.contains(currentNode)) {
int position = getPositionRelativeToDocumentElement(currentNode);
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
this.outputCommentToWriter((Comment) currentNode);
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
}
break;
case Node.PROCESSING_INSTRUCTION_NODE :
if (this._xpathNodeSet.contains(currentNode)) {
int position = getPositionRelativeToDocumentElement(currentNode);
if (position == NODE_AFTER_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
this.outputPItoWriter((ProcessingInstruction) currentNode);
if (position == NODE_BEFORE_DOCUMENT_ELEMENT) {
this._writer.write("\n");
}
}
break;
case Node.TEXT_NODE :
case Node.CDATA_SECTION_NODE :
if (this._xpathNodeSet.contains(currentNode)) {
this.outputTextToWriter(currentNode.getNodeValue());
for (Node nextSibling = currentNode.getNextSibling();
(nextSibling != null)
&& ((nextSibling.getNodeType() == Node.TEXT_NODE)
|| (nextSibling.getNodeType()
== Node.CDATA_SECTION_NODE));
nextSibling = nextSibling.getNextSibling()) {
/* The XPath data model allows to select only the first of a
* sequence of mixed text and CDATA nodes. But we must output
* them all, so we must search:
*
* @see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=6329
*/
this.outputTextToWriter(nextSibling.getNodeValue());
}
}
break;
case Node.ELEMENT_NODE :
Element currentElement = (Element) currentNode;
if (currentNodeIsVisible) {
this._writer.write("<");
this._writer.write(currentElement.getTagName());
}
// we output all Attrs which are available
Object[] attrs = handleAttributes(currentElement);
attrs = C14nHelper.sortAttributes(attrs);
for (int i = 0; i < attrs.length; i++) {
Attr attr = (Attr) attrs[i];
this.outputAttrToWriter(attr.getNodeName(), attr.getNodeValue());
}
if (currentNodeIsVisible) {
this._writer.write(">");
}
// traversal
for (Node currentChild = currentNode.getFirstChild();
currentChild != null;
currentChild = currentChild.getNextSibling()) {
canonicalizeXPathNodeSet(currentChild);
}
if (currentNodeIsVisible) {
this._writer.write("</");
this._writer.write(currentElement.getTagName());
this._writer.write(">");
}
break;
}
}
/**
* 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
* @throws IOException
*/
void outputAttrToWriter(String name, String value) throws IOException {
this._writer.write(" ");
this._writer.write(name);
this._writer.write("=\"");
int length = value.length();
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
switch (c) {
case '&' :
this._writer.write("&");
break;
case '<' :
this._writer.write("<");
break;
case '"' :
this._writer.write(""");
break;
case 0x09 : // '\t'
this._writer.write("	");
break;
case 0x0A : // '\n'
this._writer.write("
");
break;
case 0x0D : // '\r'
this._writer.write("
");
break;
default :
this._writer.write(c);
break;
}
}
this._writer.write("\"");
}
/**
* Outputs a PI to the internal Writer.
*
* @param currentPI
* @throws IOException
*/
void outputPItoWriter(ProcessingInstruction currentPI) throws IOException {
this._writer.write("<?");
String target = currentPI.getTarget();
int length = target.length();
for (int i = 0; i < length; i++) {
char c = target.charAt(i);
switch (c) {
case 0x0D :
this._writer.write("
");
break;
default :
this._writer.write(c);
break;
}
}
String data = currentPI.getData();
length = data.length();
if ((data != null) && (length > 0)) {
this._writer.write(" ");
for (int i = 0; i < length; i++) {
char c = data.charAt(i);
switch (c) {
case 0x0D :
this._writer.write("
");
break;
default :
this._writer.write(c);
break;
}
}
}
this._writer.write("?>");
}
/**
* Method outputCommentToWriter
*
* @param currentComment
* @throws IOException
*/
void outputCommentToWriter(Comment currentComment) throws IOException {
this._writer.write("<!--");
String data = currentComment.getData();
int length = data.length();
for (int i = 0; i < length; i++) {
char c = data.charAt(i);
switch (c) {
case 0x0D :
this._writer.write("
");
break;
default :
this._writer.write(c);
break;
}
}
this._writer.write("-->");
}
/**
* Outputs a Text of CDATA section to the internal Writer.
*
* @param text
* @throws IOException
*/
void outputTextToWriter(String text) throws IOException {
int length = text.length();
for (int i = 0; i < length; i++) {
char c = text.charAt(i);
switch (c) {
case '&' :
this._writer.write("&");
break;
case '<' :
this._writer.write("<");
break;
case '>' :
this._writer.write(">");
break;
case 0xD :
this._writer.write("
");
break;
default :
this._writer.write(c);
break;
}
}
}
/**
* Method handleAttributes
*
* @param E
* @throws CanonicalizationException
*/
abstract Object[] handleAttributes(Element E)
throws CanonicalizationException;
/**
* Method handleAttributesSubtree
*
* @param E
* @throws CanonicalizationException
*/
abstract Object[] handleAttributesSubtree(Element E)
throws CanonicalizationException;
}