Canonicalizer20010315Excl.java revision 0
395N/A/*
395N/A * reserved comment block
395N/A * DO NOT REMOVE OR ALTER!
395N/A */
395N/A
395N/A/*
395N/A * Copyright 1999-2004 The Apache Software Foundation.
395N/A *
395N/A * Licensed under the Apache License, Version 2.0 (the "License"); you may not
395N/A * use this file except in compliance with the License. You may obtain a copy of
395N/A * the License at
395N/A *
395N/A * http://www.apache.org/licenses/LICENSE-2.0
395N/A *
395N/A * Unless required by applicable law or agreed to in writing, software
395N/A * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
395N/A * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
395N/A * License for the specific language governing permissions and limitations under
395N/A * the License.
395N/A *
395N/A */
395N/Apackage com.sun.org.apache.xml.internal.security.c14n.implementations;
395N/A
395N/Aimport java.util.Iterator;
395N/Aimport java.util.Set;
395N/Aimport java.util.SortedSet;
395N/Aimport java.util.TreeSet;
395N/A
395N/Aimport com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
395N/Aimport com.sun.org.apache.xml.internal.security.c14n.helper.C14nHelper;
395N/Aimport com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
395N/Aimport com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces;
395N/Aimport com.sun.org.apache.xml.internal.security.utils.Constants;
395N/Aimport org.w3c.dom.Attr;
395N/Aimport org.w3c.dom.Element;
395N/Aimport org.w3c.dom.NamedNodeMap;
395N/Aimport org.w3c.dom.Node;
395N/A/**
395N/A * Implements &quot; <A
395N/A * HREF="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/">Exclusive XML
395N/A * Canonicalization, Version 1.0 </A>&quot; <BR />
395N/A * Credits: During restructuring of the Canonicalizer framework, Ren??
395N/A * Kollmorgen from Software AG submitted an implementation of ExclC14n which
395N/A * fitted into the old architecture and which based heavily on my old (and slow)
395N/A * implementation of "Canonical XML". A big "thank you" to Ren?? for this.
395N/A * <BR />
395N/A * <i>THIS </i> implementation is a complete rewrite of the algorithm.
395N/A *
395N/A * @author Christian Geuer-Pollmann <geuerp@apache.org>
395N/A * @see <a href="http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/ Exclusive#">
395N/A * XML Canonicalization, Version 1.0</a>
395N/A */
395N/Apublic abstract class Canonicalizer20010315Excl extends CanonicalizerBase {
395N/A /**
395N/A * This Set contains the names (Strings like "xmlns" or "xmlns:foo") of
395N/A * the inclusive namespaces.
395N/A */
395N/A TreeSet _inclusiveNSSet = null;
395N/A static final String XMLNS_URI=Constants.NamespaceSpecNS;
395N/A final SortedSet result = new TreeSet(COMPARE);
395N/A /**
395N/A * Constructor Canonicalizer20010315Excl
395N/A *
395N/A * @param includeComments
395N/A */
395N/A public Canonicalizer20010315Excl(boolean includeComments) {
395N/A super(includeComments);
395N/A }
395N/A
395N/A /**
395N/A * Method engineCanonicalizeSubTree
395N/A * @inheritDoc
395N/A * @param rootNode
*
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeSubTree(Node rootNode)
throws CanonicalizationException {
return this.engineCanonicalizeSubTree(rootNode, "",null);
}
/**
* Method engineCanonicalizeSubTree
* @inheritDoc
* @param rootNode
* @param inclusiveNamespaces
*
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeSubTree(Node rootNode,
String inclusiveNamespaces) throws CanonicalizationException {
return this.engineCanonicalizeSubTree(rootNode, inclusiveNamespaces,null);
}
/**
* Method engineCanonicalizeSubTree
* @param rootNode
* @param inclusiveNamespaces
* @param excl A element to exclude from the c14n process.
* @return the rootNode c14n.
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeSubTree(Node rootNode,
String inclusiveNamespaces,Node excl) throws CanonicalizationException {
this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
.prefixStr2Set(inclusiveNamespaces);
return super.engineCanonicalizeSubTree(rootNode,excl);
}
/**
*
* @param rootNode
* @param inclusiveNamespaces
* @return the rootNode c14n.
* @throws CanonicalizationException
*/
public byte[] engineCanonicalize(XMLSignatureInput rootNode,
String inclusiveNamespaces) throws CanonicalizationException {
this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
.prefixStr2Set(inclusiveNamespaces);
return super.engineCanonicalize(rootNode);
}
/**
* Method handleAttributesSubtree
* @inheritDoc
* @param E
* @throws CanonicalizationException
*/
Iterator handleAttributesSubtree(Element E,NameSpaceSymbTable ns)
throws CanonicalizationException {
// System.out.println("During the traversal, I encountered " +
// XMLUtils.getXPath(E));
// result will contain the attrs which have to be outputted
SortedSet result = this.result;
result.clear();
NamedNodeMap attrs=null;
int attrsLength = 0;
if (E.hasAttributes()) {
attrs = E.getAttributes();
attrsLength = attrs.getLength();
}
//The prefix visibly utilized(in the attribute or in the name) in the element
SortedSet visiblyUtilized =(SortedSet) _inclusiveNSSet.clone();
for (int i = 0; i < attrsLength; i++) {
Attr N = (Attr) attrs.item(i);
String NName=N.getLocalName();
String NNodeValue=N.getNodeValue();
if (!XMLNS_URI.equals(N.getNamespaceURI())) {
//Not a namespace definition.
//The Element is output element, add his prefix(if used) to visibyUtilized
String prefix = N.getPrefix();
if ( (prefix != null) && (!prefix.equals(XML) && !prefix.equals(XMLNS)) ) {
visiblyUtilized.add(prefix);
}
//Add to the result.
result.add(N);
continue;
}
if (ns.addMapping(NName, NNodeValue,N)) {
//New definition check if it is relative.
if (C14nHelper.namespaceIsRelative(NNodeValue)) {
Object exArgs[] = {E.getTagName(), NName,
N.getNodeValue()};
throw new CanonicalizationException(
"c14n.Canonicalizer.RelativeNamespace", exArgs);
}
}
}
if (E.getNamespaceURI() != null) {
String prefix = E.getPrefix();
if ((prefix == null) || (prefix.length() == 0)) {
visiblyUtilized.add(XMLNS);
} else {
visiblyUtilized.add(prefix);
}
} else {
visiblyUtilized.add(XMLNS);
}
//This can be optimezed by I don't have time
Iterator it=visiblyUtilized.iterator();
while (it.hasNext()) {
String s=(String)it.next();
Attr key=ns.getMapping(s);
if (key==null) {
continue;
}
result.add(key);
}
return result.iterator();
}
/**
* Method engineCanonicalizeXPathNodeSet
* @inheritDoc
* @param xpathNodeSet
* @param inclusiveNamespaces
* @throws CanonicalizationException
*/
public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet,
String inclusiveNamespaces) throws CanonicalizationException {
this._inclusiveNSSet = (TreeSet)InclusiveNamespaces
.prefixStr2Set(inclusiveNamespaces);
return super.engineCanonicalizeXPathNodeSet(xpathNodeSet);
}
/** @inheritDoc */
public byte[] engineCanonicalizeXPathNodeSet(Set xpathNodeSet
) throws CanonicalizationException {
return engineCanonicalizeXPathNodeSet(xpathNodeSet,"");
}
/**
* @inheritDoc
* @param E
* @throws CanonicalizationException
*/
final Iterator handleAttributes(Element E, NameSpaceSymbTable ns)
throws CanonicalizationException {
// result will contain the attrs which have to be outputted
SortedSet result = this.result;
result.clear();
NamedNodeMap attrs = null;
int attrsLength = 0;
if (E.hasAttributes()) {
attrs = E.getAttributes();
attrsLength = attrs.getLength();
}
//The prefix visibly utilized(in the attribute or in the name) in the element
Set visiblyUtilized =null;
//It's the output selected.
boolean isOutputElement = isVisible(E);
if (isOutputElement) {
visiblyUtilized = (Set) this._inclusiveNSSet.clone();
}
for (int i = 0; i < attrsLength; i++) {
Attr N = (Attr) attrs.item(i);
String NName=N.getLocalName();
String NNodeValue=N.getNodeValue();
if ( !isVisible(N) ) {
//The node is not in the nodeset(if there is a nodeset)
continue;
}
if (!XMLNS_URI.equals(N.getNamespaceURI())) {
//Not a namespace definition.
if (isOutputElement) {
//The Element is output element, add his prefix(if used) to visibyUtilized
String prefix = N.getPrefix();
if ((prefix != null) && (!prefix.equals(XML) && !prefix.equals(XMLNS)) ){
visiblyUtilized.add(prefix);
}
//Add to the result.
result.add(N);
}
continue;
}
if (ns.addMapping(NName, NNodeValue,N)) {
//New definiton check if it is relative
if (C14nHelper.namespaceIsRelative(NNodeValue)) {
Object exArgs[] = {E.getTagName(), NName,
N.getNodeValue()};
throw new CanonicalizationException(
"c14n.Canonicalizer.RelativeNamespace", exArgs);
}
}
}
if (isOutputElement) {
//The element is visible, handle the xmlns definition
Attr xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS);
if ((xmlns!=null) && (!isVisible(xmlns))) {
//There is a definition but the xmlns is not selected by the xpath.
//then xmlns=""
ns.addMapping(XMLNS,"",nullNode);
}
if (E.getNamespaceURI() != null) {
String prefix = E.getPrefix();
if ((prefix == null) || (prefix.length() == 0)) {
visiblyUtilized.add(XMLNS);
} else {
visiblyUtilized.add( prefix);
}
} else {
visiblyUtilized.add(XMLNS);
}
//This can be optimezed by I don't have time
//visiblyUtilized.addAll(this._inclusiveNSSet);
Iterator it=visiblyUtilized.iterator();
while (it.hasNext()) {
String s=(String)it.next();
Attr key=ns.getMapping(s);
if (key==null) {
continue;
}
result.add(key);
}
} else /*if (_circunvented)*/ {
Iterator it=this._inclusiveNSSet.iterator();
while (it.hasNext()) {
String s=(String)it.next();
Attr key=ns.getMappingWithoutRendered(s);
if (key==null) {
continue;
}
result.add(key);
}
}
return result.iterator();
}
}