/**
   * Returns the Attr[]s to be output for the given element. <br>
   * The code of this method is a copy of {@link #handleAttributes(Element, NameSpaceSymbTable)},
   * whereas it takes into account that subtree-c14n is -- well -- subtree-based. So if the element
   * in question isRoot of c14n, it's parent is not in the node set, as well as all other ancestors.
   *
   * @param element
   * @param ns
   * @return the Attr[]s to be output
   * @throws CanonicalizationException
   */
  @Override
  protected Iterator<Attr> handleAttributesSubtree(Element element, NameSpaceSymbTable ns)
      throws CanonicalizationException {
    if (!element.hasAttributes() && !firstCall) {
      return null;
    }
    // result will contain the attrs which have to be output
    final SortedSet<Attr> result = this.result;
    result.clear();

    if (element.hasAttributes()) {
      NamedNodeMap attrs = element.getAttributes();
      int attrsLength = attrs.getLength();

      for (int i = 0; i < attrsLength; i++) {
        Attr attribute = (Attr) attrs.item(i);
        String NUri = attribute.getNamespaceURI();
        String NName = attribute.getLocalName();
        String NValue = attribute.getValue();

        if (!XMLNS_URI.equals(NUri)) {
          // It's not a namespace attr node. Add to the result and continue.
          result.add(attribute);
        } else if (!(XML.equals(NName) && XML_LANG_URI.equals(NValue))) {
          // The default mapping for xml must not be output.
          Node n = ns.addMappingAndRender(NName, NValue, attribute);

          if (n != null) {
            // Render the ns definition
            result.add((Attr) n);
            if (C14nHelper.namespaceIsRelative(attribute)) {
              Object exArgs[] = {element.getTagName(), NName, attribute.getNodeValue()};
              throw new CanonicalizationException("c14n.Canonicalizer.RelativeNamespace", exArgs);
            }
          }
        }
      }
    }

    if (firstCall) {
      // It is the first node of the subtree
      // Obtain all the namespaces defined in the parents, and added to the output.
      ns.getUnrenderedNodes(result);
      // output the attributes in the xml namespace.
      xmlattrStack.getXmlnsAttr(result);
      firstCall = false;
    }

    return result.iterator();
  }
Example #2
0
    Shuttle(Shuttle cp, Element e) {
      this.node = e;
      this.g = cp.g;
      this.svgRoot = cp.svgRoot;
      this.shape = cp.shape;
      this.clip = cp.clip;
      this.fontSize = cp.fontSize;
      this.fontFamily = cp.fontFamily;
      this.stroke = cp.stroke;
      this.fill = cp.fill;
      this.strokeWidth = cp.strokeWidth;
      this.transform = new AffineTransform(cp.transform);
      this.opacity = cp.opacity;
      if (e.hasAttributes()) {
        NamedNodeMap atts = e.getAttributes();
        for (int i = 0; i < atts.getLength(); ++i) {

          Attr att = Attr.class.cast(atts.item(i));
          if (att.getNamespaceURI() != null) continue;
          String s = att.getName();
          String value = att.getValue();
          if (s.equals("style")) {
            for (String styles : value.split("[;]+")) {
              int j = styles.indexOf(':');
              if (j != -1) {
                applyStyle(styles.substring(0, j).trim(), styles.substring(j + 1).trim());
              }
            }

          } else {
            applyStyle(s, att.getValue());
          }
        }
      }
    }
Example #3
0
 public static void copyAttributes(SOAPElement target, Element source) {
   // easy way out: no attributes
   if (!source.hasAttributes()) return;
   final boolean traceEnabled = log.isTraceEnabled();
   // traverse attributes
   NamedNodeMap attributes = source.getAttributes();
   for (int i = 0, n = attributes.getLength(); i < n; i++) {
     Node attribute = attributes.item(i);
     String namespaceURI = attribute.getNamespaceURI();
     // isn't the attribute a namespace declaration?
     if (!BpelConstants.NS_XMLNS.equals(namespaceURI)) {
       String name = attribute.getNodeName();
       String value = attribute.getNodeValue();
       if (namespaceURI == null) {
         /*
          * use the DOM level 1 method as some SAAJ implementations complain
          * when presented a null namespace URI
          */
         target.setAttribute(name, value);
       } else {
         target.setAttributeNS(namespaceURI, name, value);
       }
       if (traceEnabled) log.trace("set attribute: " + name);
     }
   }
 }
Example #4
0
 public static void copyNamespaces(SOAPElement target, Element source) throws SOAPException {
   // easy way out: no attributes
   if (!source.hasAttributes()) return;
   final boolean traceEnabled = log.isTraceEnabled();
   // traverse attributes to discover namespace declarations
   NamedNodeMap attributes = source.getAttributes();
   for (int i = 0, n = attributes.getLength(); i < n; i++) {
     Node attribute = attributes.item(i);
     // is attribute a namespace declaration?
     if (!BpelConstants.NS_XMLNS.equals(attribute.getNamespaceURI())) continue;
     // namespace declaration format xmlns:prefix="namespaceURI" |
     // xmlns="defaultNamespaceURI"
     String namespaceURI = attribute.getNodeValue();
     String prefix = attribute.getLocalName();
     // non-default namespace declaration?
     if (!"xmlns".equals(prefix)) {
       // BPEL-195: prevent addition matching visible declaration at target
       if (namespaceURI.equals(target.getNamespaceURI(prefix))) continue;
       target.addNamespaceDeclaration(prefix, namespaceURI);
       if (traceEnabled) log.trace("added namespace declaration: " + prefix + "->" + namespaceURI);
     }
     // non-empty default namespace declaration
     else if (namespaceURI.length() > 0) {
       prefix = generatePrefix(source, DEFAULT_NAMESPACE_PREFIX);
       target.addNamespaceDeclaration(prefix, namespaceURI);
       if (traceEnabled)
         log.trace("reassigned default namespace declaration: " + prefix + "->" + namespaceURI);
     }
   }
 }
Example #5
0
 public static void copyNamespaces(final Element target, Element source) {
   // easy way out: no attributes
   if (!source.hasAttributes()) return;
   final boolean traceEnabled = log.isTraceEnabled();
   // traverse attributes to discover namespace declarations
   NamedNodeMap attributes = source.getAttributes();
   for (int i = 0, n = attributes.getLength(); i < n; i++) {
     Node attribute = attributes.item(i);
     // is attribute a namespace declaration?
     if (!BpelConstants.NS_XMLNS.equals(attribute.getNamespaceURI())) continue;
     // namespace declaration format xmlns:prefix="namespaceURI" |
     // xmlns="defaultNamespaceURI"
     String namespaceURI = attribute.getNodeValue();
     String prefix = attribute.getLocalName();
     // default namespace declaration?
     if ("xmlns".equals(prefix)) {
       // BPEL-195: prevent addition matching visible declaration at target
       if ("".equals(getPrefix(namespaceURI, target))) continue;
       addNamespaceDeclaration(target, namespaceURI);
       if (traceEnabled) log.trace("added default namespace declaration: " + namespaceURI);
     } else {
       // BPEL-195: prevent addition matching visible declaration at target
       if (prefix.equals(getPrefix(namespaceURI, target))) continue;
       addNamespaceDeclaration(target, namespaceURI, prefix);
       if (traceEnabled) log.trace("added namespace declaration: " + prefix + "->" + namespaceURI);
     }
   }
 }
  protected void handleParent(Element e, NameSpaceSymbTable ns) {
    if (!e.hasAttributes() && e.getNamespaceURI() == null) {
      return;
    }
    xmlattrStack.push(-1);
    NamedNodeMap attrs = e.getAttributes();
    int attrsLength = attrs.getLength();
    for (int i = 0; i < attrsLength; i++) {
      Attr attribute = (Attr) attrs.item(i);
      String NName = attribute.getLocalName();
      String NValue = attribute.getNodeValue();

      if (Constants.NamespaceSpecNS.equals(attribute.getNamespaceURI())) {
        if (!XML.equals(NName) || !Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
          ns.addMapping(NName, NValue, attribute);
        }
      } else if (!"id".equals(NName) && XML_LANG_URI.equals(attribute.getNamespaceURI())) {
        xmlattrStack.addXmlnsAttr(attribute);
      }
    }
    if (e.getNamespaceURI() != null) {
      String NName = e.getPrefix();
      String NValue = e.getNamespaceURI();
      String Name;
      if (NName == null || NName.equals("")) {
        NName = "xmlns";
        Name = "xmlns";
      } else {
        Name = "xmlns:" + NName;
      }
      Attr n = e.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/", Name);
      n.setValue(NValue);
      ns.addMapping(NName, NValue, n);
    }
  }
Example #7
0
  void handleParent(Element e, NameSpaceSymbTable ns) {
    if (!e.hasAttributes()) {
      return;
    }
    xmlattrStack.push(-1);
    NamedNodeMap attrs = e.getAttributes();
    int attrsLength = attrs.getLength();
    for (int i = 0; i < attrsLength; i++) {
      Attr N = (Attr) attrs.item(i);
      if (Constants.NamespaceSpecNS != N.getNamespaceURI()) {
        // Not a namespace definition, ignore.
        if (XML_LANG_URI == N.getNamespaceURI()) {
          xmlattrStack.addXmlnsAttr(N);
        }
        continue;
      }

      String NName = N.getLocalName();
      String NValue = N.getNodeValue();
      if (XML.equals(NName) && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
        continue;
      }
      ns.addMapping(NName, NValue, N);
    }
  }
Example #8
0
  @Override
  public void relink_namespace(ThreadContext context) {
    Element e = (Element) node;

    e.getOwnerDocument().renameNode(e, e.lookupNamespaceURI(e.getPrefix()), e.getNodeName());

    if (e.hasAttributes()) {
      NamedNodeMap attrs = e.getAttributes();

      for (int i = 0; i < attrs.getLength(); i++) {
        Attr attr = (Attr) attrs.item(i);
        String nsUri = "";
        String prefix = attr.getPrefix();
        String nodeName = attr.getNodeName();
        if ("xml".equals(prefix)) {
          nsUri = "http://www.w3.org/XML/1998/namespace";
        } else if ("xmlns".equals(prefix) || nodeName.equals("xmlns")) {
          nsUri = "http://www.w3.org/2000/xmlns/";
        } else {
          nsUri = attr.lookupNamespaceURI(nodeName);
        }

        e.getOwnerDocument().renameNode(attr, nsUri, nodeName);
      }
    }

    if (e.hasChildNodes()) {
      ((XmlNodeSet) children(context)).relink_namespace(context);
    }
  }
  /**
   * Float the xml:* attributes of the unselected parent nodes to the ciurrent node.
   *
   * @param E
   * @param result
   */
  private void addXmlAttributes(Element E, SortedSet result) {
    /* The processing of an element node E MUST be modified slightly when an
     * XPath node-set is given as input and the element's parent is omitted
     * from the node-set. The method for processing the attribute axis of an
     * element E in the node-set is enhanced. All element nodes along E's
     * ancestor axis are examined for nearest occurrences of attributes in
     * the xml namespace, such as xml:lang and xml:space (whether or not they
     * are in the node-set). From this list of attributes, remove any that are
     * in E's attribute axis (whether or not they are in the node-set). Then,
     * lexicographically merge this attribute list with the nodes of E's
     * attribute axis that are in the node-set. The result of visiting the
     * attribute axis is computed by processing the attribute nodes in this
     * merged attribute list.
     */

    // E is in the node-set
    Node parent = E.getParentNode();
    Map loa = new HashMap();

    if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE) && !isVisible(parent)) {

      // parent element is not in node set
      for (Node ancestor = parent;
          (ancestor != null) && (ancestor.getNodeType() == Node.ELEMENT_NODE);
          ancestor = ancestor.getParentNode()) {
        Element el = ((Element) ancestor);
        if (!el.hasAttributes()) {
          continue;
        }
        // for all ancestor elements
        NamedNodeMap ancestorAttrs = el.getAttributes();

        for (int i = 0; i < ancestorAttrs.getLength(); i++) {

          // for all attributes in the ancestor element
          Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i);

          if (XML_LANG_URI.equals(currentAncestorAttr.getNamespaceURI())) {

            // do we have an xml:* ?
            if (!E.hasAttributeNS(XML_LANG_URI, currentAncestorAttr.getLocalName())) {

              // the xml:* attr is not in E
              if (!loa.containsKey(currentAncestorAttr.getName())) {
                loa.put(currentAncestorAttr.getName(), currentAncestorAttr);
              }
            }
          }
        }
      }
    }
    result.addAll(loa.values());
  }
Example #10
0
  /**
   * This is the work horse for {@link #circumventBug2650}.
   *
   * @param node
   * @see <A HREF="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2650">Namespace axis resolution
   *     is not XPath compliant </A>
   */
  private static void circumventBug2650internal(Node node) {
    Node parent = null;
    Node sibling = null;
    final String namespaceNs = Constants.NamespaceSpecNS;
    do {
      switch (node.getNodeType()) {
        case Node.ELEMENT_NODE:
          Element element = (Element) node;
          if (!element.hasChildNodes()) break;
          if (element.hasAttributes()) {
            NamedNodeMap attributes = element.getAttributes();
            int attributesLength = attributes.getLength();

            for (Node child = element.getFirstChild();
                child != null;
                child = child.getNextSibling()) {

              if (child.getNodeType() != Node.ELEMENT_NODE) {
                continue;
              }
              Element childElement = (Element) child;

              for (int i = 0; i < attributesLength; i++) {
                Attr currentAttr = (Attr) attributes.item(i);
                if (namespaceNs != currentAttr.getNamespaceURI()) continue;
                if (childElement.hasAttributeNS(namespaceNs, currentAttr.getLocalName())) {
                  continue;
                }
                childElement.setAttributeNS(
                    namespaceNs, currentAttr.getName(), currentAttr.getNodeValue());
              }
            }
          }
        case Node.ENTITY_REFERENCE_NODE:
        case Node.DOCUMENT_NODE:
          parent = node;
          sibling = node.getFirstChild();
          break;
      }
      while ((sibling == null) && (parent != null)) {
        sibling = parent.getNextSibling();
        parent = parent.getParentNode();
      }
      ;
      if (sibling == null) {
        return;
      }

      node = sibling;
      sibling = node.getNextSibling();
    } while (true);
  }
Example #11
0
 public static void copyAttributes(Element target, Element source) {
   // easy way out: no attributes
   if (!source.hasAttributes()) return;
   // traverse attributes
   NamedNodeMap attributes = source.getAttributes();
   for (int i = 0, n = attributes.getLength(); i < n; i++) {
     Node attribute = attributes.item(i);
     String namespaceURI = attribute.getNamespaceURI();
     // isn't the attribute a namespace declaration?
     if (!BpelConstants.NS_XMLNS.equals(namespaceURI)) {
       target.setAttributeNS(namespaceURI, attribute.getNodeName(), attribute.getNodeValue());
     }
   }
 }
Example #12
0
  private void serialize(Element e, XmlSerializer s, int depth, String spaces) throws Exception {

    String name = e.getTagName();

    writeSpace(s, depth, spaces);

    s.startTag("", name);

    if (e.hasAttributes()) {
      NamedNodeMap nm = e.getAttributes();
      for (int i = 0; i < nm.getLength(); i++) {
        Attr attr = (Attr) nm.item(i);
        s.attribute("", attr.getName(), attr.getValue());
      }
    }

    if (e.hasChildNodes()) {

      NodeList nl = e.getChildNodes();

      int elements = 0;

      for (int i = 0; i < nl.getLength(); i++) {

        Node n = nl.item(i);

        short type = n.getNodeType();

        switch (type) {
          case Node.ELEMENT_NODE:
            serialize((Element) n, s, depth + 1, spaces);
            elements++;
            break;
          case Node.TEXT_NODE:
            s.text(text(n));
            break;
          case Node.CDATA_SECTION_NODE:
            s.cdsect(text(n));
            break;
        }
      }

      if (elements > 0) {
        writeSpace(s, depth, spaces);
      }
    }

    s.endTag("", name);
  }
Example #13
0
 public static void removeAttributes(Element elem) {
   if (elem.hasAttributes()) {
     NamedNodeMap attributeMap = elem.getAttributes();
     // since node maps are live, we must hold them in a separate container
     int n = attributeMap.getLength();
     Attr[] attributes = new Attr[n];
     for (int i = 0; i < n; i++) {
       attributes[i] = (Attr) attributeMap.item(i);
     }
     // now remove each attribute from the element
     for (int i = 0; i < n; i++) {
       elem.removeAttributeNode(attributes[i]);
     }
   }
 }
  /**
   * Adds to ns the definitons from the parent elements of el
   *
   * @param el
   * @param ns
   */
  static final void getParentNameSpaces(Element el, NameSpaceSymbTable ns) {
    List parents = new ArrayList();
    Node n1 = el.getParentNode();
    if (!(n1 instanceof Element)) {
      return;
    }
    // Obtain all the parents of the elemnt
    Element parent = (Element) el.getParentNode();
    while (parent != null) {
      parents.add(parent);
      Node n = parent.getParentNode();
      if (!(n instanceof Element)) {
        break;
      }
      parent = (Element) n;
    }
    // Visit them in reverse order.
    ListIterator it = parents.listIterator(parents.size());
    while (it.hasPrevious()) {
      Element ele = (Element) it.previous();
      if (!ele.hasAttributes()) {
        continue;
      }
      NamedNodeMap attrs = ele.getAttributes();
      int attrsLength = attrs.getLength();
      for (int i = 0; i < attrsLength; i++) {
        Attr N = (Attr) attrs.item(i);
        if (!Constants.NamespaceSpecNS.equals(N.getNamespaceURI())) {
          // Not a namespace definition, ignore.
          continue;
        }

        String NName = N.getLocalName();
        String NValue = N.getNodeValue();
        if (XML.equals(NName) && Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) {
          continue;
        }
        ns.addMapping(NName, NValue, N);
      }
    }
    Attr nsprefix;
    if (((nsprefix = ns.getMappingWithoutRendered("xmlns")) != null)
        && "".equals(nsprefix.getValue())) {
      ns.addMappingAndRender("xmlns", "", nullNode);
    }
  }
Example #15
0
 static final void getSetRec(
     final Node rootNode, final Set result, final Node exclude, final boolean com) {
   // Set result = new HashSet();
   if (rootNode == exclude) {
     return;
   }
   switch (rootNode.getNodeType()) {
     case Node.ELEMENT_NODE:
       result.add(rootNode);
       Element el = (Element) rootNode;
       if (el.hasAttributes()) {
         NamedNodeMap nl = ((Element) rootNode).getAttributes();
         for (int i = 0; i < nl.getLength(); i++) {
           result.add(nl.item(i));
         }
       }
       // no return keep working
     case Node.DOCUMENT_NODE:
       for (Node r = rootNode.getFirstChild(); r != null; r = r.getNextSibling()) {
         if (r.getNodeType() == Node.TEXT_NODE) {
           result.add(r);
           while ((r != null) && (r.getNodeType() == Node.TEXT_NODE)) {
             r = r.getNextSibling();
           }
           if (r == null) return;
         }
         getSetRec(r, result, exclude, com);
       }
       return;
     case Node.COMMENT_NODE:
       if (com) {
         result.add(rootNode);
       }
       return;
     case Node.DOCUMENT_TYPE_NODE:
       return;
     default:
       result.add(rootNode);
   }
   return;
 }
Example #16
0
 private static int getElementBySearching(Node root, String id, Element[] els) {
   switch (root.getNodeType()) {
     case Node.ELEMENT_NODE:
       Element el = (Element) root;
       if (el.hasAttributes()) {
         int index = names.indexOf(el.getNamespaceURI());
         if (index < 0) {
           index = 4;
         }
         if (el.getAttribute("Id").equals(id)) {
           els[index] = el;
           if (index == 0) {
             return 1;
           }
         } else if (el.getAttribute("id").equals(id)) {
           if (index != 2) {
             index = 4;
           }
           els[index] = el;
         } else if (el.getAttribute("ID").equals(id)) {
           if (index != 3) {
             index = 4;
           }
           els[index] = el;
         } else if ((index == 3)
             && (el.getAttribute("OriginalRequestID").equals(id)
                 || el.getAttribute("RequestID").equals(id)
                 || el.getAttribute("ResponseID").equals(id))) {
           els[3] = el;
         }
       }
     case Node.DOCUMENT_NODE:
       Node sibling = root.getFirstChild();
       while (sibling != null) {
         if (getElementBySearching(sibling, id, els) == 1) return 1;
         sibling = sibling.getNextSibling();
       }
   }
   return 0;
 }
  /**
   * Float the xml:* attributes of the parent nodes to the root node of c14n
   *
   * @param E the root node.
   * @param result the xml:* attributes to output.
   */
  private void addXmlAttributesSubtree(Element E, SortedSet result) {
    // E is in the node-set
    Node parent = E.getParentNode();
    Map loa = new HashMap();

    if ((parent != null) && (parent.getNodeType() == Node.ELEMENT_NODE)) {

      // parent element is not in node set
      for (Node ancestor = parent;
          (ancestor != null) && (ancestor.getNodeType() == Node.ELEMENT_NODE);
          ancestor = ancestor.getParentNode()) {
        Element el = ((Element) ancestor);
        if (!el.hasAttributes()) {
          continue;
        }
        // for all ancestor elements
        NamedNodeMap ancestorAttrs = el.getAttributes();

        for (int i = 0; i < ancestorAttrs.getLength(); i++) {
          // for all attributes in the ancestor element
          Attr currentAncestorAttr = (Attr) ancestorAttrs.item(i);

          if (XML_LANG_URI.equals(currentAncestorAttr.getNamespaceURI())) {

            // do we have an xml:* ?
            if (!E.hasAttributeNS(XML_LANG_URI, currentAncestorAttr.getLocalName())) {

              // the xml:* attr is not in E
              if (!loa.containsKey(currentAncestorAttr.getName())) {
                loa.put(currentAncestorAttr.getName(), currentAncestorAttr);
              }
            }
          }
        }
      }
    }

    result.addAll(loa.values());
  }
 /**
  * INTERNAL: When using the DOM Platform during unmarshal operations. Use the element to determine
  * if the element represents a null value. @ param element
  *
  * @return true if based on the element it represents a null value, else false.
  */
 public boolean valueIsNull(Element element) {
   // Check Nillable: Ignore any other attributes that are in addition to xsi:nil
   if (null == element) {
     return true;
   } else {
     if (isNullRepresentedByXsiNil()
         && element.hasAttributeNS(
             javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
             Constants.SCHEMA_NIL_ATTRIBUTE)) {
       return true;
     } else {
       // EMPTY_NODE - Required
       // Verify no attributes and no child nodes on the DOM element
       if (isNullRepresentedByEmptyNode()
           && !element.hasAttributes()
           && (element.getChildNodes().getLength() == 0)) {
         return true;
       } else {
         return false;
       }
     }
   }
 }
  /**
   * Returns the Attr[]s to be output for the given element. <br>
   * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has been
   * prepared using {@link org.apache.xml.security.utils.XMLUtils#circumventBug2650(
   * org.w3c.dom.Document)}.
   *
   * @param element
   * @param ns
   * @return the Attr[]s to be output
   * @throws CanonicalizationException
   */
  @Override
  protected Iterator<Attr> handleAttributes(Element element, NameSpaceSymbTable ns)
      throws CanonicalizationException {
    // result will contain the attrs which have to be output
    xmlattrStack.push(ns.getLevel());
    boolean isRealVisible = isVisibleDO(element, ns.getLevel()) == 1;
    final SortedSet<Attr> result = this.result;
    result.clear();

    if (element.hasAttributes()) {
      NamedNodeMap attrs = element.getAttributes();
      int attrsLength = attrs.getLength();

      for (int i = 0; i < attrsLength; i++) {
        Attr attribute = (Attr) attrs.item(i);
        String NUri = attribute.getNamespaceURI();
        String NName = attribute.getLocalName();
        String NValue = attribute.getValue();

        if (!XMLNS_URI.equals(NUri)) {
          // A non namespace definition node.
          if (XML_LANG_URI.equals(NUri)) {
            if (NName.equals("id")) {
              if (isRealVisible) {
                // treat xml:id like any other attribute
                // (emit it, but don't inherit it)
                result.add(attribute);
              }
            } else {
              xmlattrStack.addXmlnsAttr(attribute);
            }
          } else if (isRealVisible) {
            // The node is visible add the attribute to the list of output attributes.
            result.add(attribute);
          }
        } else if (!XML.equals(NName) || !XML_LANG_URI.equals(NValue)) {
          /* except omit namespace node with local name xml, which defines
           * the xml prefix, if its string value is
           * http://www.w3.org/XML/1998/namespace.
           */
          // add the prefix binding to the ns symb table.
          if (isVisible(attribute)) {
            if (isRealVisible || !ns.removeMappingIfRender(NName)) {
              // The xpath select this node output it if needed.
              Node n = ns.addMappingAndRender(NName, NValue, attribute);
              if (n != null) {
                result.add((Attr) n);
                if (C14nHelper.namespaceIsRelative(attribute)) {
                  Object exArgs[] = {element.getTagName(), NName, attribute.getNodeValue()};
                  throw new CanonicalizationException(
                      "c14n.Canonicalizer.RelativeNamespace", exArgs);
                }
              }
            }
          } else {
            if (isRealVisible && !XMLNS.equals(NName)) {
              ns.removeMapping(NName);
            } else {
              ns.addMapping(NName, NValue, attribute);
            }
          }
        }
      }
    }

    if (isRealVisible) {
      // The element is visible, handle the xmlns definition
      Attr xmlns = element.getAttributeNodeNS(XMLNS_URI, XMLNS);
      Node n = null;
      if (xmlns == null) {
        // No xmlns def just get the already defined.
        n = ns.getMapping(XMLNS);
      } else if (!isVisible(xmlns)) {
        // There is a definition but the xmlns is not selected by the xpath.
        // then xmlns=""
        n = ns.addMappingAndRender(XMLNS, "", nullNode);
      }
      // output the xmlns def if needed.
      if (n != null) {
        result.add((Attr) n);
      }
      // Float all xml:* attributes of the unselected parent elements to this one.
      xmlattrStack.getXmlnsAttr(result);
      ns.getUnrenderedNodes(result);
    }

    return result.iterator();
  }
  protected static String nodeToString(Node node, Set<String> parentPrefixes, String namespaceURI)
      throws Exception {
    StringBuilder b = new StringBuilder();

    if (node == null) {
      return "";
    }

    if (node instanceof Element) {
      Element element = (Element) node;
      b.append("<");
      b.append(element.getNodeName());

      Map<String, String> thisLevelPrefixes = new HashMap<>();
      if (element.getPrefix() != null && !parentPrefixes.contains(element.getPrefix())) {
        thisLevelPrefixes.put(element.getPrefix(), element.getNamespaceURI());
      }

      if (element.hasAttributes()) {
        NamedNodeMap map = element.getAttributes();
        for (int i = 0; i < map.getLength(); i++) {
          Node attr = map.item(i);
          if (attr.getNodeName().startsWith("xmlns")) continue;
          if (attr.getPrefix() != null && !parentPrefixes.contains(attr.getPrefix())) {
            thisLevelPrefixes.put(attr.getPrefix(), element.getNamespaceURI());
          }
          b.append(" ");
          b.append(attr.getNodeName());
          b.append("=\"");
          b.append(attr.getNodeValue());
          b.append("\"");
        }
      }

      if (namespaceURI != null
          && !thisLevelPrefixes.containsValue(namespaceURI)
          && !namespaceURI.equals(element.getParentNode().getNamespaceURI())) {
        b.append(" xmlns=\"").append(namespaceURI).append("\"");
      }

      for (Map.Entry<String, String> entry : thisLevelPrefixes.entrySet()) {
        b.append(" xmlns:")
            .append(entry.getKey())
            .append("=\"")
            .append(entry.getValue())
            .append("\"");
        parentPrefixes.add(entry.getKey());
      }

      NodeList children = element.getChildNodes();
      boolean hasOnlyAttributes = true;
      for (int i = 0; i < children.getLength(); i++) {
        Node child = children.item(i);
        if (child.getNodeType() != Node.ATTRIBUTE_NODE) {
          hasOnlyAttributes = false;
          break;
        }
      }
      if (!hasOnlyAttributes) {
        b.append(">");
        for (int i = 0; i < children.getLength(); i++) {
          b.append(
              nodeToString(children.item(i), parentPrefixes, children.item(i).getNamespaceURI()));
        }
        b.append("</");
        b.append(element.getNodeName());
        b.append(">");
      } else {
        b.append("/>");
      }

      for (String thisLevelPrefix : thisLevelPrefixes.keySet()) {
        parentPrefixes.remove(thisLevelPrefix);
      }

    } else if (node.getNodeValue() != null) {
      b.append(encodeText(node.getNodeValue(), node instanceof Attr));
    }

    return b.toString();
  }
Example #21
0
  /**
   * Returns the Attr[]s to be outputted for the given element. <br>
   * IMPORTANT: This method expects to work on a modified DOM tree, i.e. a DOM which has been
   * prepared using {@link
   * com.sun.org.apache.xml.internal.security.utils.XMLUtils#circumventBug2650(
   * org.w3c.dom.Document)}.
   *
   * @param E
   * @param ns
   * @return the Attr[]s to be outputted
   * @throws CanonicalizationException
   */
  Iterator handleAttributes(Element E, NameSpaceSymbTable ns) throws CanonicalizationException {
    // result will contain the attrs which have to be outputted
    xmlattrStack.push(ns.getLevel());
    boolean isRealVisible = isVisibleDO(E, ns.getLevel()) == 1;
    NamedNodeMap attrs = null;
    int attrsLength = 0;
    if (E.hasAttributes()) {
      attrs = E.getAttributes();
      attrsLength = attrs.getLength();
    }

    SortedSet result = this.result;
    result.clear();

    for (int i = 0; i < attrsLength; i++) {
      Attr N = (Attr) attrs.item(i);
      String NUri = N.getNamespaceURI();

      if (XMLNS_URI != NUri) {
        // A non namespace definition node.
        if (XML_LANG_URI == NUri) {
          xmlattrStack.addXmlnsAttr(N);
        } else if (isRealVisible) {
          // The node is visible add the attribute to the list of output attributes.
          result.add(N);
        }
        // keep working
        continue;
      }

      String NName = N.getLocalName();
      String NValue = N.getValue();
      if ("xml".equals(NName) && XML_LANG_URI.equals(NValue)) {
        /* except omit namespace node with local name xml, which defines
         * the xml prefix, if its string value is http://www.w3.org/XML/1998/namespace.
         */
        continue;
      }
      // add the prefix binding to the ns symb table.
      // ns.addInclusiveMapping(NName,NValue,N,isRealVisible);
      if (isVisible(N)) {
        if (!isRealVisible && ns.removeMappingIfRender(NName)) {
          continue;
        }
        // The xpath select this node output it if needed.
        // Node n=ns.addMappingAndRenderXNodeSet(NName,NValue,N,isRealVisible);
        Node n = ns.addMappingAndRender(NName, NValue, N);
        if (n != null) {
          result.add(n);
          if (C14nHelper.namespaceIsRelative(N)) {
            Object exArgs[] = {E.getTagName(), NName, N.getNodeValue()};
            throw new CanonicalizationException("c14n.Canonicalizer.RelativeNamespace", exArgs);
          }
        }
      } else {
        if (isRealVisible && NName != XMLNS) {
          ns.removeMapping(NName);
        } else {
          ns.addMapping(NName, NValue, N);
        }
      }
    }
    if (isRealVisible) {
      // The element is visible, handle the xmlns definition
      Attr xmlns = E.getAttributeNodeNS(XMLNS_URI, XMLNS);
      Node n = null;
      if (xmlns == null) {
        // No xmlns def just get the already defined.
        n = ns.getMapping(XMLNS);
      } else if (!isVisible(xmlns)) {
        // There is a definition but the xmlns is not selected by the xpath.
        // then xmlns=""
        n = ns.addMappingAndRender(XMLNS, "", nullNode);
      }
      // output the xmlns def if needed.
      if (n != null) {
        result.add(n);
      }
      // Float all xml:* attributes of the unselected parent elements to this one.
      // addXmlAttributes(E,result);
      xmlattrStack.getXmlnsAttr(result);
      ns.getUnrenderedNodes(result);
    }

    return result.iterator();
  }
  /**
   * Called to serialize a DOM element. Equivalent to calling {@link #startElement}, {@link
   * #endElement} and serializing everything inbetween, but better optimized.
   */
  protected void serializeElement(Element elem) throws IOException {
    Attr attr;
    NamedNodeMap attrMap;
    int i;
    Node child;
    ElementState state;
    String name;
    String value;
    String tagName;

    String prefix, localUri;
    String uri;
    if (fNamespaces) {
      // local binder stores namespace declaration
      // that has been printed out during namespace fixup of
      // the current element
      fLocalNSBinder.reset();

      // add new namespace context
      fNSBinder.pushContext();
    }

    if (DEBUG) {
      System.out.println(
          "==>startElement: " + elem.getNodeName() + " ns=" + elem.getNamespaceURI());
    }
    tagName = elem.getTagName();
    state = getElementState();
    if (isDocumentState()) {
      // If this is the root element handle it differently.
      // If the first root element in the document, serialize
      // the document's DOCTYPE. Space preserving defaults
      // to that of the output format.

      if (!_started) {
        startDocument(tagName);
      }
    } else {
      // For any other element, if first in parent, then
      // close parent's opening tag and use the parent's
      // space preserving.
      if (state.empty) _printer.printText('>');
      // Must leave CData section first
      if (state.inCData) {
        _printer.printText("]]>");
        state.inCData = false;
      }
      // Indent this element on a new line if the first
      // content of the parent element or immediately
      // following an element.
      if (_indenting
          && !state.preserveSpace
          && (state.empty || state.afterElement || state.afterComment)) _printer.breakLine();
    }

    // Do not change the current element state yet.
    // This only happens in endElement().
    fPreserveSpace = state.preserveSpace;

    int length = 0;
    attrMap = null;
    // retrieve attributes
    if (elem.hasAttributes()) {
      attrMap = elem.getAttributes();
      length = attrMap.getLength();
    }

    if (!fNamespaces) { // no namespace fixup should be performed

      // serialize element name
      _printer.printText('<');
      _printer.printText(tagName);
      _printer.indent();

      // For each attribute print it's name and value as one part,
      // separated with a space so the element can be broken on
      // multiple lines.
      for (i = 0; i < length; ++i) {
        attr = (Attr) attrMap.item(i);
        name = attr.getName();
        value = attr.getValue();
        if (value == null) value = "";
        printAttribute(name, value, attr.getSpecified(), attr);
      }
    } else { // do namespace fixup

      // REVISIT: some optimization could probably be done to avoid traversing
      //          attributes twice.
      //

      // ---------------------------------------
      // record all valid namespace declarations
      // before attempting to fix element's namespace
      // ---------------------------------------

      for (i = 0; i < length; i++) {

        attr = (Attr) attrMap.item(i);
        uri = attr.getNamespaceURI();
        // check if attribute is a namespace decl
        if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {

          value = attr.getNodeValue();
          if (value == null) {
            value = XMLSymbols.EMPTY_STRING;
          }

          if (value.equals(NamespaceContext.XMLNS_URI)) {
            if (fDOMErrorHandler != null) {
              String msg =
                  DOMMessageFormatter.formatMessage(
                      DOMMessageFormatter.XML_DOMAIN, "CantBindXMLNS", null);
              modifyDOMError(msg, DOMError.SEVERITY_ERROR, null, attr);
              boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
              if (!continueProcess) {
                // stop the namespace fixup and validation
                throw new RuntimeException(
                    DOMMessageFormatter.formatMessage(
                        DOMMessageFormatter.SERIALIZER_DOMAIN, "SerializationStopped", null));
              }
            }
          } else {
            prefix = attr.getPrefix();
            prefix =
                (prefix == null || prefix.length() == 0)
                    ? XMLSymbols.EMPTY_STRING
                    : fSymbolTable.addSymbol(prefix);
            String localpart = fSymbolTable.addSymbol(attr.getLocalName());
            if (prefix == XMLSymbols.PREFIX_XMLNS) { // xmlns:prefix
              value = fSymbolTable.addSymbol(value);
              // record valid decl
              if (value.length() != 0) {
                fNSBinder.declarePrefix(localpart, value);
              } else {
                // REVISIT: issue error on invalid declarations
                //          xmlns:foo = ""
              }
              continue;
            } else { // xmlns
              // empty prefix is always bound ("" or some string)

              value = fSymbolTable.addSymbol(value);
              fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, value);
              continue;
            }
          } // end-else: valid declaration
        } // end-if: namespace declaration
      } // end-for

      // -----------------------
      // get element uri/prefix
      // -----------------------
      uri = elem.getNamespaceURI();
      prefix = elem.getPrefix();

      // ----------------------
      // output element name
      // ----------------------
      // REVISIT: this could be removed if we always convert empty string to null
      //          for the namespaces.
      if ((uri != null && prefix != null) && uri.length() == 0 && prefix.length() != 0) {
        // uri is an empty string and element has some prefix
        // the namespace alg later will fix up the namespace attributes
        // remove element prefix
        prefix = null;
        _printer.printText('<');
        _printer.printText(elem.getLocalName());
        _printer.indent();
      } else {
        _printer.printText('<');
        _printer.printText(tagName);
        _printer.indent();
      }

      // ---------------------------------------------------------
      // Fix up namespaces for element: per DOM L3
      // Need to consider the following cases:
      //
      // case 1: <foo:elem xmlns:ns1="myURI" xmlns="default"/>
      // Assume "foo", "ns1" are declared on the parent. We should not miss
      // redeclaration for both "ns1" and default namespace. To solve this
      // we add a local binder that stores declaration only for current element.
      // This way we avoid outputing duplicate declarations for the same element
      // as well as we are not omitting redeclarations.
      //
      // case 2: <elem xmlns="" xmlns="default"/>
      // We need to bind default namespace to empty string, to be able to
      // omit duplicate declarations for the same element
      //
      // case 3: <xsl:stylesheet xmlns:xsl="http://xsl">
      // We create another element body bound to the "http://xsl" namespace
      // as well as namespace attribute rebounding xsl to another namespace.
      // <xsl:body xmlns:xsl="http://another">
      // Need to make sure that the new namespace decl value is changed to
      // "http://xsl"
      //
      // ---------------------------------------------------------
      // check if prefix/namespace is correct for current element
      // ---------------------------------------------------------

      if (uri != null) { // Element has a namespace
        uri = fSymbolTable.addSymbol(uri);
        prefix =
            (prefix == null || prefix.length() == 0)
                ? XMLSymbols.EMPTY_STRING
                : fSymbolTable.addSymbol(prefix);
        if (fNSBinder.getURI(prefix) == uri) {
          // The xmlns:prefix=namespace or xmlns="default" was declared at parent.
          // The binder always stores mapping of empty prefix to "".
          // (NOTE: local binder does not store this kind of binding!)
          // Thus the case where element was declared with uri="" (with or without a prefix)
          // will be covered here.

        } else {
          // the prefix is either undeclared
          // or
          // conflict: the prefix is bound to another URI
          if (fNamespacePrefixes) {
            printNamespaceAttr(prefix, uri);
          }
          fLocalNSBinder.declarePrefix(prefix, uri);
          fNSBinder.declarePrefix(prefix, uri);
        }
      } else { // Element has no namespace
        if (elem.getLocalName() == null) {
          //  DOM Level 1 node!
          if (fDOMErrorHandler != null) {
            String msg =
                DOMMessageFormatter.formatMessage(
                    DOMMessageFormatter.DOM_DOMAIN,
                    "NullLocalElementName",
                    new Object[] {elem.getNodeName()});
            modifyDOMError(msg, DOMError.SEVERITY_ERROR, null, elem);
            boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
            // REVISIT: should we terminate upon request?
            if (!continueProcess) {
              throw new RuntimeException(
                  DOMMessageFormatter.formatMessage(
                      DOMMessageFormatter.SERIALIZER_DOMAIN, "SerializationStopped", null));
            }
          }
        } else { // uri=null and no colon (DOM L2 node)
          uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING);

          if (uri != null && uri.length() > 0) {
            // there is a default namespace decl that is bound to
            // non-zero length uri, output xmlns=""
            if (fNamespacePrefixes) {
              printNamespaceAttr(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
            }
            fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
            fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);
          }
        }
      }

      // -----------------------------------------
      // Fix up namespaces for attributes: per DOM L3
      // check if prefix/namespace is correct the attributes
      // -----------------------------------------

      for (i = 0; i < length; i++) {

        attr = (Attr) attrMap.item(i);
        value = attr.getValue();
        name = attr.getNodeName();

        uri = attr.getNamespaceURI();

        // Fix attribute that was declared with a prefix and namespace=""
        if (uri != null && uri.length() == 0) {
          uri = null;
          // we must remove prefix for this attribute
          name = attr.getLocalName();
        }

        if (DEBUG) {
          System.out.println("==>process attribute: " + attr.getNodeName());
        }
        // make sure that value is never null.
        if (value == null) {
          value = XMLSymbols.EMPTY_STRING;
        }

        if (uri != null) { // attribute has namespace !=null
          prefix = attr.getPrefix();
          prefix = prefix == null ? XMLSymbols.EMPTY_STRING : fSymbolTable.addSymbol(prefix);
          String localpart = fSymbolTable.addSymbol(attr.getLocalName());

          // ---------------------------------------------------
          // print namespace declarations namespace declarations
          // ---------------------------------------------------
          if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {
            // check if we need to output this declaration
            prefix = attr.getPrefix();
            prefix =
                (prefix == null || prefix.length() == 0)
                    ? XMLSymbols.EMPTY_STRING
                    : fSymbolTable.addSymbol(prefix);
            localpart = fSymbolTable.addSymbol(attr.getLocalName());
            if (prefix == XMLSymbols.PREFIX_XMLNS) { // xmlns:prefix
              localUri = fLocalNSBinder.getURI(localpart); // local prefix mapping
              value = fSymbolTable.addSymbol(value);
              if (value.length() != 0) {
                if (localUri == null) {
                  // declaration was not printed while fixing element namespace binding

                  // If the DOM Level 3 namespace-prefixes feature is set to false
                  // do not print xmlns attributes
                  if (fNamespacePrefixes) {
                    printNamespaceAttr(localpart, value);
                  }

                  // case 4: <elem xmlns:xx="foo" xx:attr=""/>
                  // where attribute is bound to "bar".
                  // If the xmlns:xx is output here first, later we should not
                  // redeclare "xx" prefix. Instead we would pick up different prefix
                  // for the attribute.
                  // final: <elem xmlns:xx="foo" NS1:attr="" xmlns:NS1="bar"/>
                  fLocalNSBinder.declarePrefix(localpart, value);
                }
              } else {
                // REVISIT: issue error on invalid declarations
                //          xmlns:foo = ""
              }
              continue;
            } else { // xmlns
              // empty prefix is always bound ("" or some string)

              uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING);
              localUri = fLocalNSBinder.getURI(XMLSymbols.EMPTY_STRING);
              value = fSymbolTable.addSymbol(value);
              if (localUri == null) {
                // declaration was not printed while fixing element namespace binding
                if (fNamespacePrefixes) {
                  printNamespaceAttr(XMLSymbols.EMPTY_STRING, value);
                }
                // case 4 does not apply here since attributes can't use
                // default namespace
              }
              continue;
            }
          }
          uri = fSymbolTable.addSymbol(uri);

          // find if for this prefix a URI was already declared
          String declaredURI = fNSBinder.getURI(prefix);

          if (prefix == XMLSymbols.EMPTY_STRING || declaredURI != uri) {
            // attribute has no prefix (default namespace decl does not apply to attributes)
            // OR
            // attribute prefix is not declared
            // OR
            // conflict: attr URI does not match the prefix in scope

            name = attr.getNodeName();
            // Find if any prefix for attributes namespace URI is available
            // in the scope
            String declaredPrefix = fNSBinder.getPrefix(uri);

            if (declaredPrefix != null && declaredPrefix != XMLSymbols.EMPTY_STRING) {
              // use the prefix that was found
              prefix = declaredPrefix;
              name = prefix + ":" + localpart;
            } else {
              if (DEBUG) {
                System.out.println("==> cound not find prefix for the attribute: " + prefix);
              }

              if (prefix != XMLSymbols.EMPTY_STRING && fLocalNSBinder.getURI(prefix) == null) {
                // the current prefix is not null and it has no in scope declaration

                // use this prefix
              } else {
                // find a prefix following the pattern "NS" +index (starting at 1)
                // make sure this prefix is not declared in the current scope.
                int counter = 1;
                prefix = fSymbolTable.addSymbol(PREFIX + counter++);
                while (fLocalNSBinder.getURI(prefix) != null) {
                  prefix = fSymbolTable.addSymbol(PREFIX + counter++);
                }
                name = prefix + ":" + localpart;
              }
              // add declaration for the new prefix
              if (fNamespacePrefixes) {
                printNamespaceAttr(prefix, uri);
              }
              value = fSymbolTable.addSymbol(value);
              fLocalNSBinder.declarePrefix(prefix, value);
              fNSBinder.declarePrefix(prefix, uri);
            }

            // change prefix for this attribute
          }

          printAttribute(
              name, (value == null) ? XMLSymbols.EMPTY_STRING : value, attr.getSpecified(), attr);
        } else { // attribute uri == null
          if (attr.getLocalName() == null) {
            if (fDOMErrorHandler != null) {
              String msg =
                  DOMMessageFormatter.formatMessage(
                      DOMMessageFormatter.DOM_DOMAIN,
                      "NullLocalAttrName",
                      new Object[] {attr.getNodeName()});
              modifyDOMError(msg, DOMError.SEVERITY_ERROR, null, attr);
              boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);
              if (!continueProcess) {
                // stop the namespace fixup and validation
                throw new RuntimeException(
                    DOMMessageFormatter.formatMessage(
                        DOMMessageFormatter.SERIALIZER_DOMAIN, "SerializationStopped", null));
              }
            }
            printAttribute(name, value, attr.getSpecified(), attr);
          } else { // uri=null and no colon

            // no fix up is needed: default namespace decl does not
            // apply to attributes
            printAttribute(name, value, attr.getSpecified(), attr);
          }
        }
      } // end loop for attributes
    } // end namespace fixup algorithm

    // If element has children, then serialize them, otherwise
    // serialize en empty tag.
    if (elem.hasChildNodes()) {
      // Enter an element state, and serialize the children
      // one by one. Finally, end the element.
      state = enterElementState(null, null, tagName, fPreserveSpace);
      state.doCData = _format.isCDataElement(tagName);
      state.unescaped = _format.isNonEscapingElement(tagName);
      child = elem.getFirstChild();
      while (child != null) {
        serializeNode(child);
        child = child.getNextSibling();
      }
      if (fNamespaces) {
        fNSBinder.popContext();
      }
      endElementIO(null, null, tagName);
    } else {
      if (DEBUG) {
        System.out.println("==>endElement: " + elem.getNodeName());
      }
      if (fNamespaces) {
        fNSBinder.popContext();
      }
      _printer.unindent();
      _printer.printText("/>");
      // After element but parent element is no longer empty.
      state.afterElement = true;
      state.afterComment = false;
      state.empty = false;
      if (isDocumentState()) _printer.flush();
    }
  }