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.params;
  22 
  23 
  24 
  25 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
  26 import com.sun.org.apache.xml.internal.security.transforms.TransformParam;
  27 import com.sun.org.apache.xml.internal.security.utils.ElementProxy;
  28 import com.sun.org.apache.xml.internal.security.utils.HelperNodeList;
  29 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
  30 import org.w3c.dom.Document;
  31 import org.w3c.dom.Element;
  32 import org.w3c.dom.Node;
  33 import org.w3c.dom.NodeList;
  34 
  35 
  36 /**
  37  * Implements the parameters for the <A
  38  * HREF="http://www.w3.org/TR/xmldsig-filter2/">XPath Filter v2.0</A>.
  39  *
  40  * @author $Author: mullan $
  41  * @see <A HREF="http://www.w3.org/TR/xmldsig-filter2/">XPath Filter v2.0 (TR)</A>
  42  * @see <A HREF="http://www.w3.org/Signature/Drafts/xmldsig-xfilter2/">XPath Filter v2.0 (editors copy)</A>
  43  */
  44 public class XPath2FilterContainer extends ElementProxy
  45         implements TransformParam {
  46 
  47    /** Field _ATT_FILTER */
  48    private static final String _ATT_FILTER = "Filter";
  49 
  50    /** Field _ATT_FILTER_VALUE_INTERSECT */
  51    private static final String _ATT_FILTER_VALUE_INTERSECT = "intersect";
  52 
  53    /** Field _ATT_FILTER_VALUE_SUBTRACT */
  54    private static final String _ATT_FILTER_VALUE_SUBTRACT = "subtract";
  55 
  56    /** Field _ATT_FILTER_VALUE_UNION */
  57    private static final String _ATT_FILTER_VALUE_UNION = "union";
  58 
  59    /** Field INTERSECT */
  60    public static final String INTERSECT =
  61       XPath2FilterContainer._ATT_FILTER_VALUE_INTERSECT;
  62 
  63    /** Field SUBTRACT */
  64    public static final String SUBTRACT =
  65       XPath2FilterContainer._ATT_FILTER_VALUE_SUBTRACT;
  66 
  67    /** Field UNION */
  68    public static final String UNION =
  69       XPath2FilterContainer._ATT_FILTER_VALUE_UNION;
  70 
  71    /** Field _TAG_XPATH2 */
  72    public static final String _TAG_XPATH2 = "XPath";
  73 
  74    /** Field XPathFiler2NS */
  75    public static final String XPathFilter2NS =
  76       "http://www.w3.org/2002/06/xmldsig-filter2";
  77 
  78    /**
  79     * Constructor XPath2FilterContainer
  80     *
  81     */
  82    private XPath2FilterContainer() {
  83 
  84       // no instantiation
  85    }
  86 
  87    /**
  88     * Constructor XPath2FilterContainer
  89     *
  90     * @param doc
  91     * @param xpath2filter
  92     * @param filterType
  93     */
  94    private XPath2FilterContainer(Document doc, String xpath2filter,
  95                                  String filterType) {
  96 
  97       super(doc);
  98 
  99       this._constructionElement
 100          .setAttributeNS(null, XPath2FilterContainer._ATT_FILTER, filterType);
 101       this._constructionElement.appendChild(doc.createTextNode(xpath2filter));
 102    }
 103 
 104    /**
 105     * Constructor XPath2FilterContainer
 106     *
 107     * @param element
 108     * @param BaseURI
 109     * @throws XMLSecurityException
 110     */
 111    private XPath2FilterContainer(Element element, String BaseURI)
 112            throws XMLSecurityException {
 113 
 114       super(element, BaseURI);
 115 
 116       String filterStr = this._constructionElement.getAttributeNS(null,
 117                             XPath2FilterContainer._ATT_FILTER);
 118 
 119       if (!filterStr
 120               .equals(XPath2FilterContainer
 121               ._ATT_FILTER_VALUE_INTERSECT) &&!filterStr
 122                  .equals(XPath2FilterContainer
 123                  ._ATT_FILTER_VALUE_SUBTRACT) &&!filterStr
 124                     .equals(XPath2FilterContainer._ATT_FILTER_VALUE_UNION)) {
 125          Object exArgs[] = { XPath2FilterContainer._ATT_FILTER, filterStr,
 126                              XPath2FilterContainer._ATT_FILTER_VALUE_INTERSECT
 127                              + ", "
 128                              + XPath2FilterContainer._ATT_FILTER_VALUE_SUBTRACT
 129                              + " or "
 130                              + XPath2FilterContainer._ATT_FILTER_VALUE_UNION };
 131 
 132          throw new XMLSecurityException("attributeValueIllegal", exArgs);
 133       }
 134    }
 135 
 136    /**
 137     * Creates a new XPath2FilterContainer with the filter type "intersect".
 138     *
 139     * @param doc
 140     * @param xpath2filter
 141     * @return the filter.
 142     */
 143    public static XPath2FilterContainer newInstanceIntersect(Document doc,
 144            String xpath2filter) {
 145 
 146       return new XPath2FilterContainer(doc, xpath2filter,
 147                                        XPath2FilterContainer
 148                                           ._ATT_FILTER_VALUE_INTERSECT);
 149    }
 150 
 151    /**
 152     * Creates a new XPath2FilterContainer with the filter type "subtract".
 153     *
 154     * @param doc
 155     * @param xpath2filter
 156     * @return the filter.
 157     */
 158    public static XPath2FilterContainer newInstanceSubtract(Document doc,
 159            String xpath2filter) {
 160 
 161       return new XPath2FilterContainer(doc, xpath2filter,
 162                                        XPath2FilterContainer
 163                                           ._ATT_FILTER_VALUE_SUBTRACT);
 164    }
 165 
 166    /**
 167     * Creates a new XPath2FilterContainer with the filter type "union".
 168     *
 169     * @param doc
 170     * @param xpath2filter
 171     * @return the filter
 172     */
 173    public static XPath2FilterContainer newInstanceUnion(Document doc,
 174            String xpath2filter) {
 175 
 176       return new XPath2FilterContainer(doc, xpath2filter,
 177                                        XPath2FilterContainer
 178                                           ._ATT_FILTER_VALUE_UNION);
 179    }
 180 
 181    /**
 182     * Method newInstances
 183     *
 184     * @param doc
 185     * @param params
 186     * @return the nodelist with the data
 187     */
 188    public static NodeList newInstances(Document doc, String[][] params) {
 189 
 190       HelperNodeList nl = new HelperNodeList();
 191 
 192       XMLUtils.addReturnToElement(doc, nl);
 193 
 194       for (int i = 0; i < params.length; i++) {
 195          String type = params[i][0];
 196          String xpath = params[i][1];
 197 
 198          if (!(type.equals(XPath2FilterContainer
 199                  ._ATT_FILTER_VALUE_INTERSECT) || type
 200                     .equals(XPath2FilterContainer
 201                     ._ATT_FILTER_VALUE_SUBTRACT) || type
 202                        .equals(XPath2FilterContainer
 203                           ._ATT_FILTER_VALUE_UNION))) {
 204             throw new IllegalArgumentException("The type(" + i + ")=\"" + type
 205                                                + "\" is illegal");
 206          }
 207 
 208          XPath2FilterContainer c = new XPath2FilterContainer(doc, xpath, type);
 209 
 210          nl.appendChild(c.getElement());
 211          XMLUtils.addReturnToElement(doc, nl);
 212       }
 213 
 214       return nl;
 215    }
 216 
 217    /**
 218     * Creates a XPath2FilterContainer from an existing Element; needed for verification.
 219     *
 220     * @param element
 221     * @param BaseURI
 222     * @return the filter
 223     *
 224     * @throws XMLSecurityException
 225     */
 226    public static XPath2FilterContainer newInstance(
 227            Element element, String BaseURI) throws XMLSecurityException {
 228       return new XPath2FilterContainer(element, BaseURI);
 229    }
 230 
 231    /**
 232     * Returns <code>true</code> if the <code>Filter</code> attribute has value "intersect".
 233     *
 234     * @return <code>true</code> if the <code>Filter</code> attribute has value "intersect".
 235     */
 236    public boolean isIntersect() {
 237 
 238       return this._constructionElement
 239          .getAttributeNS(null, XPath2FilterContainer._ATT_FILTER)
 240          .equals(XPath2FilterContainer._ATT_FILTER_VALUE_INTERSECT);
 241    }
 242 
 243    /**
 244     * Returns <code>true</code> if the <code>Filter</code> attribute has value "subtract".
 245     *
 246     * @return <code>true</code> if the <code>Filter</code> attribute has value "subtract".
 247     */
 248    public boolean isSubtract() {
 249 
 250       return this._constructionElement
 251          .getAttributeNS(null, XPath2FilterContainer._ATT_FILTER)
 252          .equals(XPath2FilterContainer._ATT_FILTER_VALUE_SUBTRACT);
 253    }
 254 
 255    /**
 256     * Returns <code>true</code> if the <code>Filter</code> attribute has value "union".
 257     *
 258     * @return <code>true</code> if the <code>Filter</code> attribute has value "union".
 259     */
 260    public boolean isUnion() {
 261 
 262       return this._constructionElement
 263          .getAttributeNS(null, XPath2FilterContainer._ATT_FILTER)
 264          .equals(XPath2FilterContainer._ATT_FILTER_VALUE_UNION);
 265    }
 266 
 267    /**
 268     * Returns the XPath 2 Filter String
 269     *
 270     * @return the XPath 2 Filter String
 271     */
 272    public String getXPathFilterStr() {
 273       return this.getTextFromTextChild();
 274    }
 275 
 276    /**
 277     * Returns the first Text node which contains information from the XPath 2
 278     * Filter String. We must use this stupid hook to enable the here() function
 279     * to work.
 280     *
 281     * $todo$ I dunno whether this crashes: <XPath> here()<!-- comment -->/ds:Signature[1]</XPath>
 282     * @return the first Text node which contains information from the XPath 2 Filter String
 283     */
 284    public Node getXPathFilterTextNode() {
 285 
 286       NodeList children = this._constructionElement.getChildNodes();
 287       int length = children.getLength();
 288 
 289       for (int i = 0; i < length; i++) {
 290          if (children.item(i).getNodeType() == Node.TEXT_NODE) {
 291             return children.item(i);
 292          }
 293       }
 294 
 295       return null;
 296    }
 297 
 298    /**
 299     * Method getBaseLocalName
 300     *
 301     * @return the XPATH2 tag
 302     */
 303    public final String getBaseLocalName() {
 304       return XPath2FilterContainer._TAG_XPATH2;
 305    }
 306 
 307    /**
 308     * Method getBaseNamespace
 309     *
 310     * @return XPATH2 tag namespace
 311     */
 312    public final String getBaseNamespace() {
 313       return XPath2FilterContainer.XPathFilter2NS;
 314    }
 315 }