1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/**
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the
11 * "License"); you may not use this file except in compliance
12 * with the License. You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an
18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 * KIND, either express or implied. See the License for the
20 * specific language governing permissions and limitations
21 * under the License.
22 */
23package com.sun.org.apache.xml.internal.security.c14n.implementations;
24
25import java.io.IOException;
26import java.io.OutputStream;
27import java.util.Iterator;
28import java.util.Set;
29import java.util.SortedSet;
30import java.util.TreeSet;
31
32import javax.xml.parsers.ParserConfigurationException;
33
34import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;
35import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
36import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
37import org.w3c.dom.Attr;
38import org.w3c.dom.Comment;
39import org.w3c.dom.Element;
40import org.w3c.dom.NamedNodeMap;
41import org.w3c.dom.Node;
42import org.w3c.dom.ProcessingInstruction;
43import org.xml.sax.SAXException;
44
45/**
46 * Serializes the physical representation of the subtree. All the attributes
47 * present in the subtree are emitted. The attributes are sorted within an element,
48 * with the namespace declarations appearing before the regular attributes.
49 * This algorithm is not a true canonicalization since equivalent subtrees
50 * may produce different output. It is therefore unsuitable for digital signatures.
51 * This same property makes it ideal for XML Encryption Syntax and Processing,
52 * because the decrypted XML content will share the same physical representation
53 * as the original XML content that was encrypted.
54 */
55public class CanonicalizerPhysical extends CanonicalizerBase {
56
57    private final SortedSet<Attr> result = new TreeSet<Attr>(COMPARE);
58
59    /**
60     * Constructor Canonicalizer20010315
61     */
62    public CanonicalizerPhysical() {
63        super(true);
64    }
65
66    /**
67     * Always throws a CanonicalizationException.
68     *
69     * @param xpathNodeSet
70     * @param inclusiveNamespaces
71     * @return none it always fails
72     * @throws CanonicalizationException always
73     */
74    public byte[] engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet, String inclusiveNamespaces)
75        throws CanonicalizationException {
76
77        /** $todo$ well, should we throw UnsupportedOperationException ? */
78        throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
79    }
80
81    /**
82     * Always throws a CanonicalizationException.
83     *
84     * @param rootNode
85     * @param inclusiveNamespaces
86     * @return none it always fails
87     * @throws CanonicalizationException
88     */
89    public byte[] engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces)
90        throws CanonicalizationException {
91
92        /** $todo$ well, should we throw UnsupportedOperationException ? */
93        throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
94    }
95
96    /**
97     * Returns the Attr[]s to be output for the given element.
98     * <br>
99     * The code of this method is a copy of {@link #handleAttributes(Element,
100     * NameSpaceSymbTable)},
101     * whereas it takes into account that subtree-c14n is -- well -- subtree-based.
102     * So if the element in question isRoot of c14n, it's parent is not in the
103     * node set, as well as all other ancestors.
104     *
105     * @param element
106     * @param ns
107     * @return the Attr[]s to be output
108     * @throws CanonicalizationException
109     */
110    @Override
111    protected Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns)
112        throws CanonicalizationException {
113        if (!element.hasAttributes()) {
114            return null;
115        }
116
117        // result will contain all the attrs declared directly on that element
118        final SortedSet<Attr> result = this.result;
119        result.clear();
120
121        if (element.hasAttributes()) {
122            NamedNodeMap attrs = element.getAttributes();
123            int attrsLength = attrs.getLength();
124
125            for (int i = 0; i < attrsLength; i++) {
126                Attr attribute = (Attr) attrs.item(i);
127                result.add(attribute);
128            }
129        }
130
131        return result.iterator();
132    }
133
134    /**
135     * Returns the Attr[]s to be output for the given element.
136     *
137     * @param element
138     * @param ns
139     * @return the Attr[]s to be output
140     * @throws CanonicalizationException
141     */
142    @Override
143    protected Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns)
144        throws CanonicalizationException {
145
146        /** $todo$ well, should we throw UnsupportedOperationException ? */
147        throw new CanonicalizationException("c14n.Canonicalizer.UnsupportedOperation");
148    }
149
150    protected void circumventBugIfNeeded(XMLSignatureInput input)
151        throws CanonicalizationException, ParserConfigurationException, IOException, SAXException {
152        // nothing to do
153    }
154
155    @Override
156    protected void handleParent(Element e, NameSpaceSymbTable ns) {
157        // nothing to do
158    }
159
160    /** @inheritDoc */
161    public final String engineGetURI() {
162        return Canonicalizer.ALGO_ID_C14N_PHYSICAL;
163    }
164
165    /** @inheritDoc */
166    public final boolean engineGetIncludeComments() {
167        return true;
168    }
169
170    @Override
171    protected void outputPItoWriter(ProcessingInstruction currentPI,
172                                    OutputStream writer, int position) throws IOException {
173        // Processing Instructions before or after the document element are not treated specially
174        super.outputPItoWriter(currentPI, writer, NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT);
175    }
176
177    @Override
178    protected void outputCommentToWriter(Comment currentComment,
179                                         OutputStream writer, int position) throws IOException {
180        // Comments before or after the document element are not treated specially
181        super.outputCommentToWriter(currentComment, writer, NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT);
182    }
183
184}
185