View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.wss4j.policy.builders;
20  
21  import org.apache.neethi.Assertion;
22  import org.apache.neethi.AssertionBuilderFactory;
23  import org.apache.neethi.builders.AssertionBuilder;
24  import org.apache.wss4j.policy.SP11Constants;
25  import org.apache.wss4j.policy.SP13Constants;
26  import org.apache.wss4j.policy.SPConstants;
27  import org.apache.wss4j.policy.SPUtils;
28  import org.apache.wss4j.policy.model.SignedElements;
29  import org.apache.wss4j.policy.model.XPath;
30  import org.w3c.dom.Attr;
31  import org.w3c.dom.Element;
32  import org.w3c.dom.NamedNodeMap;
33  
34  import javax.xml.namespace.QName;
35  import java.util.ArrayList;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  
40  public class SignedElementsBuilder implements AssertionBuilder<Element> {
41  
42      @Override
43      public Assertion build(Element element, AssertionBuilderFactory factory) throws IllegalArgumentException {
44  
45          final SPConstants.SPVersion spVersion = SPConstants.SPVersion.getSPVersion(element.getNamespaceURI());
46          final String xPathVersion = getXPathVersion(element);
47          final List<XPath> xPaths = getXPathExpressions(element, spVersion);
48          final List<XPath> xPaths2 = getXPath2Expressions(element, spVersion);
49          xPaths.addAll(xPaths2);
50          SignedElements signedElements = new SignedElements(spVersion, xPathVersion, xPaths);
51          signedElements.setOptional(SPUtils.isOptional(element));
52          signedElements.setIgnorable(SPUtils.isIgnorable(element));
53          return signedElements;
54      }
55  
56      protected List<XPath> getXPathExpressions(Element element, SPConstants.SPVersion spVersion) {
57          List<XPath> xPaths = new ArrayList<>();
58  
59          Element child = SPUtils.getFirstChildElement(element);
60          while (child != null) {
61              QName xpathExpression = spVersion.getSPConstants().getXPathExpression();
62              if (SPConstants.XPATH_EXPR.equals(child.getLocalName())
63                  && xpathExpression.getNamespaceURI().equals(child.getNamespaceURI())) {
64                  Map<String, String> declaredNamespaces = new HashMap<>();
65                  addDeclaredNamespaces(child, declaredNamespaces);
66                  xPaths.add(new XPath(child.getTextContent().trim(), XPath.Version.V1, null, declaredNamespaces));
67              }
68              child = SPUtils.getNextSiblingElement(child);
69          }
70          return xPaths;
71      }
72  
73      protected List<XPath> getXPath2Expressions(Element element, SPConstants.SPVersion spVersion) {
74          List<XPath> xPaths = new ArrayList<>();
75  
76          Element child = SPUtils.getFirstChildElement(element);
77          while (child != null) {
78              QName xpathExpression = spVersion.getSPConstants().getXPath2Expression();
79              if (SPConstants.XPATH2_EXPR.equals(child.getLocalName())
80                  && xpathExpression.getNamespaceURI().equals(child.getNamespaceURI())) {
81                  Map<String, String> declaredNamespaces = new HashMap<>();
82                  addDeclaredNamespaces(child, declaredNamespaces);
83                  String filter = child.getAttributeNS(null, SPConstants.FILTER);
84                  if (filter == null || filter.length() == 0) {
85                      throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
86                  }
87                  xPaths.add(new XPath(child.getTextContent().trim(), XPath.Version.V2, filter, declaredNamespaces));
88              }
89              child = SPUtils.getNextSiblingElement(child);
90          }
91          return xPaths;
92      }
93  
94      protected String getXPathVersion(Element element) {
95          String xPathVersion = element.getAttributeNS(null, SPConstants.XPATH_VERSION);
96          if (xPathVersion == null || xPathVersion.length() == 0) {
97              xPathVersion = "1.0";
98          }
99          return xPathVersion;
100     }
101 
102     protected void addDeclaredNamespaces(Element element, Map<String, String> declaredNamespaces) {
103         if (element.getParentNode() != null && element.getParentNode() instanceof Element) {
104             addDeclaredNamespaces((Element) element.getParentNode(), declaredNamespaces);
105         }
106         NamedNodeMap map = element.getAttributes();
107         for (int x = 0; x < map.getLength(); x++) {
108             Attr attr = (Attr) map.item(x);
109             if ("xmlns".equals(attr.getPrefix())) {
110                 declaredNamespaces.put(attr.getLocalName(), attr.getValue());
111             }
112         }
113     }
114 
115     @Override
116     public QName[] getKnownElements() {
117         return new QName[]{SP13Constants.SIGNED_ELEMENTS, SP11Constants.SIGNED_ELEMENTS};
118     }
119 }