author | mullan |
Mon, 26 Sep 2011 17:20:45 -0700 | |
changeset 10694 | cf59e2badd14 |
parent 1337 | e8d6cef36199 |
child 11674 | a657f8ba55fc |
permissions | -rw-r--r-- |
2 | 1 |
/* |
2 |
* reserved comment block |
|
3 |
* DO NOT REMOVE OR ALTER! |
|
4 |
*/ |
|
5 |
/* |
|
6 |
* Copyright 1999-2004 The Apache Software Foundation. |
|
7 |
* |
|
8 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
9 |
* you may not use this file except in compliance with the License. |
|
10 |
* You may obtain a copy of the License at |
|
11 |
* |
|
12 |
* http://www.apache.org/licenses/LICENSE-2.0 |
|
13 |
* |
|
14 |
* Unless required by applicable law or agreed to in writing, software |
|
15 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
16 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
17 |
* See the License for the specific language governing permissions and |
|
18 |
* limitations under the License. |
|
19 |
* |
|
20 |
*/ |
|
21 |
package com.sun.org.apache.xml.internal.security.transforms.implementations; |
|
22 |
||
23 |
||
24 |
||
25 |
import java.io.IOException; |
|
26 |
import java.util.ArrayList; |
|
1337 | 27 |
import java.util.HashSet; |
28 |
import java.util.Iterator; |
|
2 | 29 |
import java.util.List; |
1337 | 30 |
import java.util.Set; |
2 | 31 |
|
32 |
import javax.xml.parsers.ParserConfigurationException; |
|
33 |
import javax.xml.transform.TransformerException; |
|
34 |
||
35 |
import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException; |
|
36 |
import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException; |
|
37 |
import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; |
|
38 |
import com.sun.org.apache.xml.internal.security.signature.NodeFilter; |
|
39 |
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput; |
|
1337 | 40 |
import com.sun.org.apache.xml.internal.security.transforms.Transform; |
2 | 41 |
import com.sun.org.apache.xml.internal.security.transforms.TransformSpi; |
42 |
import com.sun.org.apache.xml.internal.security.transforms.TransformationException; |
|
43 |
import com.sun.org.apache.xml.internal.security.transforms.Transforms; |
|
44 |
import com.sun.org.apache.xml.internal.security.transforms.params.XPath2FilterContainer; |
|
45 |
import com.sun.org.apache.xml.internal.security.utils.CachedXPathAPIHolder; |
|
46 |
import com.sun.org.apache.xml.internal.security.utils.CachedXPathFuncHereAPI; |
|
47 |
import com.sun.org.apache.xml.internal.security.utils.XMLUtils; |
|
48 |
import org.w3c.dom.DOMException; |
|
49 |
import org.w3c.dom.Document; |
|
50 |
import org.w3c.dom.Element; |
|
51 |
import org.w3c.dom.Node; |
|
52 |
import org.w3c.dom.NodeList; |
|
53 |
import org.xml.sax.SAXException; |
|
54 |
||
55 |
/** |
|
56 |
* Implements the <I>XML Signature XPath Filter v2.0</I> |
|
57 |
* |
|
58 |
* @author $Author: mullan $ |
|
59 |
* @see <A HREF="http://www.w3.org/TR/xmldsig-filter2/">XPath Filter v2.0 (TR)</A> |
|
60 |
* @see <a HREF="http://www.w3.org/Signature/Drafts/xmldsig-xfilter2/">XPath Filter v2.0 (editors copy)</a> |
|
61 |
*/ |
|
62 |
public class TransformXPath2Filter extends TransformSpi { |
|
63 |
||
64 |
/** {@link java.util.logging} logging facility */ |
|
65 |
// static java.util.logging.Logger log = |
|
66 |
// java.util.logging.Logger.getLogger( |
|
67 |
// TransformXPath2Filter.class.getName()); |
|
68 |
||
69 |
/** Field implementedTransformURI */ |
|
70 |
public static final String implementedTransformURI = |
|
71 |
Transforms.TRANSFORM_XPATH2FILTER; |
|
72 |
//J- |
|
73 |
// contains the type of the filter |
|
74 |
||
75 |
// contains the node set |
|
76 |
||
77 |
/** |
|
78 |
* Method engineGetURI |
|
79 |
* |
|
80 |
* @inheritDoc |
|
81 |
*/ |
|
82 |
protected String engineGetURI() { |
|
83 |
return implementedTransformURI; |
|
84 |
} |
|
85 |
||
86 |
||
87 |
||
88 |
/** |
|
89 |
* Method enginePerformTransform |
|
90 |
* @inheritDoc |
|
91 |
* @param input |
|
92 |
* |
|
93 |
* @throws TransformationException |
|
94 |
*/ |
|
1337 | 95 |
protected XMLSignatureInput enginePerformTransform(XMLSignatureInput input, Transform _transformObject) |
2 | 96 |
throws TransformationException { |
1337 | 97 |
CachedXPathAPIHolder.setDoc(_transformObject.getElement().getOwnerDocument()); |
2 | 98 |
try { |
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
99 |
List<NodeList> unionNodes=new ArrayList<NodeList>(); |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
100 |
List<NodeList> substractNodes=new ArrayList<NodeList>(); |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
101 |
List<NodeList> intersectNodes=new ArrayList<NodeList>(); |
2 | 102 |
|
103 |
CachedXPathFuncHereAPI xPathFuncHereAPI = |
|
104 |
new CachedXPathFuncHereAPI(CachedXPathAPIHolder.getCachedXPathAPI()); |
|
105 |
||
106 |
||
107 |
Element []xpathElements =XMLUtils.selectNodes( |
|
1337 | 108 |
_transformObject.getElement().getFirstChild(), |
2 | 109 |
XPath2FilterContainer.XPathFilter2NS, |
110 |
XPath2FilterContainer._TAG_XPATH2); |
|
111 |
int noOfSteps = xpathElements.length; |
|
112 |
||
113 |
||
114 |
if (noOfSteps == 0) { |
|
115 |
Object exArgs[] = { Transforms.TRANSFORM_XPATH2FILTER, "XPath" }; |
|
116 |
||
117 |
throw new TransformationException("xml.WrongContent", exArgs); |
|
118 |
} |
|
119 |
||
120 |
Document inputDoc = null; |
|
121 |
if (input.getSubNode() != null) { |
|
122 |
inputDoc = XMLUtils.getOwnerDocument(input.getSubNode()); |
|
123 |
} else { |
|
124 |
inputDoc = XMLUtils.getOwnerDocument(input.getNodeSet()); |
|
125 |
} |
|
126 |
||
127 |
for (int i = 0; i < noOfSteps; i++) { |
|
128 |
Element xpathElement =XMLUtils.selectNode( |
|
1337 | 129 |
_transformObject.getElement().getFirstChild(), |
2 | 130 |
XPath2FilterContainer.XPathFilter2NS, |
131 |
XPath2FilterContainer._TAG_XPATH2,i); |
|
132 |
XPath2FilterContainer xpathContainer = |
|
133 |
XPath2FilterContainer.newInstance(xpathElement, |
|
134 |
input.getSourceURI()); |
|
135 |
||
136 |
||
137 |
NodeList subtreeRoots = xPathFuncHereAPI.selectNodeList(inputDoc, |
|
138 |
xpathContainer.getXPathFilterTextNode(), |
|
139 |
CachedXPathFuncHereAPI.getStrFromNode(xpathContainer.getXPathFilterTextNode()), |
|
140 |
xpathContainer.getElement()); |
|
141 |
if (xpathContainer.isIntersect()) { |
|
142 |
intersectNodes.add(subtreeRoots); |
|
143 |
} else if (xpathContainer.isSubtract()) { |
|
144 |
substractNodes.add(subtreeRoots); |
|
145 |
} else if (xpathContainer.isUnion()) { |
|
146 |
unionNodes.add(subtreeRoots); |
|
147 |
} |
|
148 |
} |
|
149 |
||
150 |
||
1337 | 151 |
input.addNodeFilter(new XPath2NodeFilter(convertNodeListToSet(unionNodes), |
152 |
convertNodeListToSet(substractNodes),convertNodeListToSet(intersectNodes))); |
|
2 | 153 |
input.setNodeSet(true); |
154 |
return input; |
|
155 |
} catch (TransformerException ex) { |
|
156 |
throw new TransformationException("empty", ex); |
|
157 |
} catch (DOMException ex) { |
|
158 |
throw new TransformationException("empty", ex); |
|
159 |
} catch (CanonicalizationException ex) { |
|
160 |
throw new TransformationException("empty", ex); |
|
161 |
} catch (InvalidCanonicalizerException ex) { |
|
162 |
throw new TransformationException("empty", ex); |
|
163 |
} catch (XMLSecurityException ex) { |
|
164 |
throw new TransformationException("empty", ex); |
|
165 |
} catch (SAXException ex) { |
|
166 |
throw new TransformationException("empty", ex); |
|
167 |
} catch (IOException ex) { |
|
168 |
throw new TransformationException("empty", ex); |
|
169 |
} catch (ParserConfigurationException ex) { |
|
170 |
throw new TransformationException("empty", ex); |
|
171 |
} |
|
172 |
} |
|
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
173 |
static Set<Node> convertNodeListToSet(List<NodeList> l){ |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
174 |
Set<Node> result=new HashSet<Node>(); |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
175 |
|
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
176 |
for (NodeList rootNodes : l) { |
1337 | 177 |
int length = rootNodes.getLength(); |
178 |
for (int i = 0; i < length; i++) { |
|
179 |
Node rootNode = rootNodes.item(i); |
|
180 |
result.add(rootNode); |
|
181 |
} |
|
182 |
} |
|
183 |
return result; |
|
184 |
} |
|
2 | 185 |
} |
186 |
||
187 |
class XPath2NodeFilter implements NodeFilter { |
|
1337 | 188 |
boolean hasUnionNodes; |
189 |
boolean hasSubstractNodes; |
|
190 |
boolean hasIntersectNodes; |
|
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
191 |
XPath2NodeFilter(Set<Node> unionNodes, Set<Node> substractNodes, |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
192 |
Set<Node> intersectNodes) { |
2 | 193 |
this.unionNodes=unionNodes; |
1337 | 194 |
hasUnionNodes=!unionNodes.isEmpty(); |
2 | 195 |
this.substractNodes=substractNodes; |
1337 | 196 |
hasSubstractNodes=!substractNodes.isEmpty(); |
2 | 197 |
this.intersectNodes=intersectNodes; |
1337 | 198 |
hasIntersectNodes=!intersectNodes.isEmpty(); |
2 | 199 |
} |
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
200 |
Set<Node> unionNodes; |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
201 |
Set<Node> substractNodes; |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
202 |
Set<Node> intersectNodes; |
2 | 203 |
|
204 |
||
205 |
/** |
|
206 |
* @see com.sun.org.apache.xml.internal.security.signature.NodeFilter#isNodeInclude(org.w3c.dom.Node) |
|
207 |
*/ |
|
1337 | 208 |
public int isNodeInclude(Node currentNode) { |
209 |
int result=1; |
|
210 |
||
211 |
if (hasSubstractNodes && rooted(currentNode, substractNodes)) { |
|
212 |
result = -1; |
|
213 |
} else if (hasIntersectNodes && !rooted(currentNode, intersectNodes)) { |
|
214 |
result = 0; |
|
2 | 215 |
} |
216 |
||
1337 | 217 |
//TODO OPTIMIZE |
218 |
if (result==1) |
|
219 |
return 1; |
|
220 |
if (hasUnionNodes) { |
|
221 |
if (rooted(currentNode, unionNodes)) { |
|
222 |
return 1; |
|
223 |
} |
|
224 |
result=0; |
|
225 |
} |
|
226 |
return result; |
|
2 | 227 |
|
228 |
} |
|
1337 | 229 |
int inSubstract=-1; |
230 |
int inIntersect=-1; |
|
231 |
int inUnion=-1; |
|
232 |
public int isNodeIncludeDO(Node n, int level) { |
|
233 |
int result=1; |
|
234 |
if (hasSubstractNodes) { |
|
235 |
if ((inSubstract==-1) || (level<=inSubstract)) { |
|
236 |
if (inList(n, substractNodes)) { |
|
237 |
inSubstract=level; |
|
238 |
} else { |
|
239 |
inSubstract=-1; |
|
240 |
} |
|
241 |
} |
|
242 |
if (inSubstract!=-1){ |
|
243 |
result=-1; |
|
244 |
} |
|
245 |
} |
|
246 |
if (result!=-1){ |
|
247 |
if (hasIntersectNodes) { |
|
248 |
if ((inIntersect==-1) || (level<=inIntersect)) { |
|
249 |
if (!inList(n, intersectNodes)) { |
|
250 |
inIntersect=-1; |
|
251 |
result=0; |
|
252 |
} else { |
|
253 |
inIntersect=level; |
|
254 |
} |
|
255 |
} |
|
256 |
} |
|
257 |
} |
|
258 |
||
259 |
if (level<=inUnion) |
|
260 |
inUnion=-1; |
|
261 |
if (result==1) |
|
262 |
return 1; |
|
263 |
if (hasUnionNodes) { |
|
264 |
if ((inUnion==-1) && inList(n, unionNodes)) { |
|
265 |
inUnion=level; |
|
266 |
} |
|
267 |
if (inUnion!=-1) |
|
268 |
return 1; |
|
269 |
result=0; |
|
270 |
} |
|
271 |
||
272 |
return result; |
|
273 |
} |
|
2 | 274 |
|
275 |
/** |
|
276 |
* Method rooted |
|
277 |
* @param currentNode |
|
278 |
* @param nodeList |
|
279 |
* |
|
280 |
* @return if rooted bye the rootnodes |
|
281 |
*/ |
|
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
282 |
static boolean rooted(Node currentNode, Set<Node> nodeList ) { |
1337 | 283 |
if (nodeList.contains(currentNode)) { |
284 |
return true; |
|
285 |
} |
|
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
286 |
|
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
287 |
for(Node rootNode : nodeList) { |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
288 |
if (XMLUtils.isDescendantOrSelf(rootNode,currentNode)) { |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
289 |
return true; |
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
290 |
} |
2 | 291 |
} |
292 |
return false; |
|
293 |
} |
|
1337 | 294 |
|
295 |
/** |
|
296 |
* Method rooted |
|
297 |
* @param currentNode |
|
298 |
* @param nodeList |
|
299 |
* |
|
300 |
* @return if rooted bye the rootnodes |
|
301 |
*/ |
|
10694
cf59e2badd14
7088502: Security libraries don't build with javac -Werror
mullan
parents:
1337
diff
changeset
|
302 |
static boolean inList(Node currentNode, Set<Node> nodeList ) { |
1337 | 303 |
return nodeList.contains(currentNode); |
304 |
} |
|
2 | 305 |
} |