diff --git a/core/commons/che-core-commons-xml/pom.xml b/core/commons/che-core-commons-xml/pom.xml
deleted file mode 100644
index 63c5451590..0000000000
--- a/core/commons/che-core-commons-xml/pom.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
- 4.0.0
-
- che-core-commons-parent
- org.eclipse.che.core
- 7.37.0-SNAPSHOT
-
- che-core-commons-xml
- jar
- Che Core :: Commons :: XML
-
- false
-
-
-
- com.google.guava
- guava
-
-
- org.slf4j
- slf4j-api
-
-
- org.testng
- testng
- test
-
-
-
-
-
- com.mycila
- license-maven-plugin
-
-
- **/test-xml-files/**
-
-
-
-
-
-
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/Attribute.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/Attribute.java
deleted file mode 100644
index be0a82402a..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/Attribute.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-/** @author Eugene Voevodin */
-public final class Attribute {
-
- private final Element container;
- private final QName name;
- private String value;
-
- Attribute(Element container, String name, String value) {
- this.name = new QName(name);
- this.container = container;
- this.value = value;
- }
-
- public String getName() {
- return name.getName();
- }
-
- public String getPrefix() {
- return name.getPrefix();
- }
-
- public String getValue() {
- return value;
- }
-
- public Element getElement() {
- return container;
- }
-
- public boolean hasPrefix() {
- return name.hasPrefix();
- }
-
- public void remove() {
- container.removeAttribute(name.getName());
- }
-
- public Attribute setValue(String value) {
- this.value = value;
- container.setAttributeValue(this);
- return this;
- }
-
- public String asString() {
- final StringBuilder sb = new StringBuilder();
- if (hasPrefix()) {
- sb.append(getPrefix()).append(':');
- }
- return sb.append(name).append('=').append('"').append(value).append('"').toString();
- }
-
- @Override
- public String toString() {
- return asString();
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/Element.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/Element.java
deleted file mode 100644
index fa8bdb3744..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/Element.java
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * Copyright (c) 2012-2021 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-import static java.util.Collections.emptyList;
-import static java.util.Objects.requireNonNull;
-import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE;
-import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.asElement;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.asElements;
-import static org.w3c.dom.Node.DOCUMENT_NODE;
-import static org.w3c.dom.Node.ELEMENT_NODE;
-import static org.w3c.dom.Node.TEXT_NODE;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import org.eclipse.che.commons.xml.XMLTree.Segment;
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * XMLTree element which provides abilities to fetch and update xml document data.
- *
- *
Delegates for related {@link org.w3c.dom.Element}
- *
- * @author Eugene Voevodin
- */
-public final class Element {
-
- private final XMLTree xmlTree;
-
- Segment start;
- Segment end;
- List text;
-
- org.w3c.dom.Element delegate;
-
- Element(XMLTree xmlTree) {
- this.xmlTree = xmlTree;
- }
-
- /**
- * Returns name of element as prefix:name. If element doesn't have prefix only local name
- * will be returned
- *
- * @return name of element tag as prefix:name
- * @throws XMLTreeException when {@link #remove()} has been invoked on this element instance
- * @see org.w3c.dom.Element#getTagName()
- */
- public String getName() {
- checkNotRemoved();
- return delegate.getTagName();
- }
-
- /**
- * Returns local name of element
- *
- * @return element local name
- * @throws XMLTreeException when this element has been removed from xml tree
- * @see org.w3c.dom.Element#getLocalName()
- */
- public String getLocalName() {
- checkNotRemoved();
- return delegate.getLocalName();
- }
-
- /**
- * Returns element name prefix or {@code null} if element name is not prefixed
- *
- * @return element name prefix
- * @throws XMLTreeException when this element has been removed from xml tree
- * @see org.w3c.dom.Element#getPrefix()
- */
- public String getPrefix() {
- checkNotRemoved();
- return delegate.getPrefix();
- }
-
- /**
- * Returns element parent or {@code null} if element doesn't have parent.
- *
- * @return element parent or {@code null} if element is xml root
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element getParent() {
- checkNotRemoved();
- return asElement(delegate.getParentNode());
- }
-
- /**
- * Searches for element sibling with given name. If more than one sibling was found throws {@link
- * XMLTreeException}. If sibling with given name doesn't exist returns {@code null}.
- *
- *
Note that {@link #getName} method used to compare element names.
- *
- * @param name sibling name to search
- * @return element sibling with given name or {@code null} if sibling with given name was
- * not found
- * @throws XMLTreeException when element has more than one sibling with given name or this
- * element has been removed from xml tree
- * @throws NullPointerException when name parameter is {@code null}
- */
- public Element getSingleSibling(String name) {
- checkNotRemoved();
- requireNonNull(name, "Non-null sibling name required.");
- Element target = null;
- for (Element sibling : asElements(delegate.getParentNode().getChildNodes())) {
- if (this != sibling && sibling.getName().equals(name)) {
- if (target != null) {
- throw new XMLTreeException(
- "Element " + name + " has more than one sibling with name " + name);
- }
- target = sibling;
- }
- }
- return target;
- }
-
- /**
- * Searches for element child with given name. If element has more then only child with given name
- * then {@link XMLTreeException} will be thrown. If child with given name doesn't exist returns
- * {@code null}
- *
- *
Note that {@link #getName} method used to compare element names.
- *
- * @param name name to search child
- * @return child element with given name or {@code null} if element with given name was not found
- * @throws XMLTreeException when element has more than one child with given name or this
- * element has been removed from xml tree
- * @throws NullPointerException when name parameter is {@code null}
- */
- public Element getSingleChild(String name) {
- checkNotRemoved();
- requireNonNull(name, "Non-null child name required.");
- for (Element child : asElements(delegate.getChildNodes())) {
- if (name.equals(child.getName())) {
- if (child.hasSibling(name)) {
- throw new XMLTreeException(
- "Element " + name + " has more than one child with the name " + name);
- }
- return child;
- }
- }
- return null;
- }
-
- /**
- * Returns last element child or {@code null} if element doesn't have children
- *
- * @return last child element or {@code null} if this element doesn't have children
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element getLastChild() {
- checkNotRemoved();
- final Node lastChild = delegate.getLastChild();
- if (lastChild != null && lastChild.getNodeType() != ELEMENT_NODE) {
- return asElement(previousElementNode(lastChild));
- }
- return asElement(lastChild);
- }
-
- /**
- * Returns first element child or {@code null} if element doesn't have children
- *
- * @return first child element or {@code null} if this element doesn't have children
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element getFirstChild() {
- checkNotRemoved();
- final Node firstChild = delegate.getFirstChild();
- if (firstChild.getNodeType() != ELEMENT_NODE) {
- return asElement(nextElementNode(firstChild));
- }
- return asElement(firstChild);
- }
-
- /**
- * Returns element children or empty list when element doesn't have children
- *
- * @return list of element children
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public List getChildren() {
- checkNotRemoved();
- return asElements(delegate.getChildNodes());
- }
-
- /**
- * Returns children mapped with given mapper or empty list when element doesn't have children
- *
- * @param mapper function which will be applied on each child element
- * @param mapper result type
- * @return list of element children which are mapped with given mapper
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public List getChildren(ElementMapper extends R> mapper) {
- checkNotRemoved();
- return asElements(delegate.getChildNodes(), mapper);
- }
-
- /**
- * Returns element text content.
- *
- *
Note that only element text going to be fetched, no CDATA or children text content.
- *
- * @return element text content
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public String getText() {
- checkNotRemoved();
- return fetchText();
- }
-
- /**
- * Returns {@code true} if element has at least one sibling with given name, otherwise returns
- * {@code false}.
- *
- * @return {@code true} if element has at least one singling with given name, otherwise {@code
- * false}.
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when name parameter is {@code null}
- */
- public boolean hasSibling(String name) {
- checkNotRemoved();
- requireNonNull(name, "Non-null sibling name required.");
- final NodeList nodes = delegate.getParentNode().getChildNodes();
- for (int i = 0; i < nodes.getLength(); i++) {
- if (nodes.item(i) != delegate && name.equals(nodes.item(i).getNodeName())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns {@code true} if this element instance is xml root element, otherwise returns {@code
- * false}
- *
- * @return {@code true} if element has parent, otherwise {@code false}
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public boolean hasParent() {
- checkNotRemoved();
- return delegate.getParentNode() != null
- && delegate.getParentNode().getNodeType() != DOCUMENT_NODE;
- }
-
- /**
- * Returns previous element sibling or {@code null} when element doesn't have previous sibling
- *
- * @return previous element sibling or {@code null} when element doesn't have previous sibling
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element getPreviousSibling() {
- checkNotRemoved();
- return asElement(previousElementNode(delegate));
- }
-
- /**
- * Returns next element sibling or {@code null} if element doesn't have next sibling
- *
- * @return next element sibling or {@code null} if element doesn't have next sibling
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element getNextSibling() {
- checkNotRemoved();
- return asElement(nextElementNode(delegate));
- }
-
- /**
- * Returns element attributes or empty list if element doesn't have attributes.
- *
- *
When element doesn't have attributes returns {@link java.util.Collections#emptyList()} which
- * is unmodifiable, so clients should not use list 'update' methods.
- *
- * @return list of element attributes or empty list if element doesn't have attributes
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public List getAttributes() {
- checkNotRemoved();
- if (delegate != null && delegate.hasAttributes()) {
- final NamedNodeMap attributes = delegate.getAttributes();
- final List copy = new ArrayList<>(attributes.getLength());
- for (int i = 0; i < attributes.getLength(); i++) {
- final Node item = attributes.item(i);
- copy.add(asAttribute(item));
- }
- return copy;
- }
- return emptyList();
- }
-
- /**
- * Returns list of element sibling or empty list if element doesn't have siblings.
- *
- * @return list of element sibling
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public List getSiblings() {
- checkNotRemoved();
- final List siblings = asElements(delegate.getParentNode().getChildNodes());
- siblings.remove(asElement(delegate));
- return siblings;
- }
-
- /**
- * Returns {@code true} if element has at least one child with given name, otherwise returns
- * {@code false}.
- *
- * @param name child name to check
- * @return {@code true} if element has at least one child with given name, otherwise {@code false}
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when name parameter is {@code null}
- */
- public boolean hasChild(String name) {
- checkNotRemoved();
- requireNonNull(name, "Non-null child name required.");
- final NodeList nodes = delegate.getChildNodes();
- for (int i = 0; i < nodes.getLength(); i++) {
- if (name.equals(nodes.item(i).getNodeName())) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns {@code true} if element has at least one child or {@code false} if doesn't
- *
- * @return {@code true} if element has at least one child or {@code false} if doesn't
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public boolean hasChildren() {
- checkNotRemoved();
- final NodeList childNodes = delegate.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++) {
- if (childNodes.item(i).getNodeType() == ELEMENT_NODE) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Sets new text content to element
- *
- * @param newText new text content
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when newText parameter is {@code null}
- */
- public Element setText(String newText) {
- checkNotRemoved();
- requireNonNull(newText, "Non-null new text required.");
- if (!newText.equals(getText())) {
- removeTextNodes();
- delegate.appendChild(document().createTextNode(newText));
- // let tree do dirty job
- xmlTree.updateText(this);
- }
- return this;
- }
-
- /**
- * Returns text content of child with given name.
- *
- * @param childName child name to fetch text content
- * @return child text or {@code null} if child doesn't exist or element has more then only child
- * with given name
- */
- public String getChildText(String childName) {
- return getChildTextOrDefault(childName, null);
- }
-
- /**
- * Returns text content of child with given name or default value if child doesn't exist or it has
- * sibling with same name
- *
- * @param childName name of child
- * @param defaultValue value which will be returned if child doesn't exist or it has sibling with
- * same name
- * @return child text
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when childName parameter is {@code null}
- */
- public String getChildTextOrDefault(String childName, String defaultValue) {
- checkNotRemoved();
- requireNonNull(childName, "Non-null child name required.");
- return hasSingleChild(childName) ? getSingleChild(childName).getText() : defaultValue;
- }
-
- /**
- * Returns {@code true} if element has only sibling with given name or {@code false} if element
- * has more then 1 or 0 siblings with given name
- *
- * @param childName name of sibling
- * @return {@code true} if element has only sibling with given name otherwise {@code false}
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when childName parameter is {@code null}
- */
- public boolean hasSingleChild(String childName) {
- checkNotRemoved();
- requireNonNull(childName, "Non-null child name required.");
- for (Element child : asElements(delegate.getChildNodes())) {
- if (childName.equals(child.getName())) {
- return !child.hasSibling(childName);
- }
- }
- return false;
- }
-
- /**
- * Removes single element child. If child does not exist nothing will be done
- *
- * @param name child name to removeElement
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element removeChild(String name) {
- checkNotRemoved();
- final Element child = getSingleChild(name);
- if (child != null) {
- child.remove();
- }
- return this;
- }
-
- /**
- * Removes current element and related children from xml
- *
- * @throws XMLTreeException when this element has been removed from xml tree or this element is
- * root element
- */
- public void remove() {
- checkNotRemoved();
- notPermittedOnRootElement();
- if (hasChildren()) {
- for (Element element : getChildren()) {
- element.remove();
- }
- }
- // let tree do dirty job
- xmlTree.removeElement(this);
- // remove self from document
- delegate.getParentNode().removeChild(delegate);
- // if references to 'this' element exist
- // we should disallow ability to use delegate
- delegate = null;
- }
-
- /**
- * Removes children which names equal to given name
- *
- * @param name name to remove children
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element removeChildren(String name) {
- checkNotRemoved();
- final List matched = new LinkedList<>();
- final NodeList nodes = delegate.getChildNodes();
- for (int i = 0; i < nodes.getLength(); i++) {
- if (name.equals(nodes.item(i).getNodeName())) {
- matched.add(nodes.item(i));
- }
- }
- for (Node node : matched) {
- asElement(node).remove();
- }
- return this;
- }
-
- /**
- * Sets new attribute to element. If element has attribute with given name attribute value will be
- * replaced with new value
- *
- * @param name attribute name
- * @param value attribute value
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element setAttribute(String name, String value) {
- return setAttribute(new NewAttribute(name, value));
- }
-
- /**
- * Sets new attribute to element. If element has attribute with {@code newAttribute#name} then
- * existing attribute value will be replaced with {@code newAttribute#value}.
- *
- * @param newAttribute attribute that should be added to element
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public Element setAttribute(NewAttribute newAttribute) {
- checkNotRemoved();
- requireNonNull(newAttribute, "Required not null new attribute");
- // if tree already contains element replace value
- if (hasAttribute(newAttribute.getName())) {
- final Attribute attr = getAttribute(newAttribute.getName());
- attr.setValue(newAttribute.getValue());
- return this;
- }
- //
- if (newAttribute.hasPrefix()) {
- delegate.setAttributeNodeNS(createAttrNSNode(newAttribute));
- } else {
- delegate.setAttributeNode(createAttrNode(newAttribute));
- }
- // let tree do dirty job
- xmlTree.insertAttribute(newAttribute, this);
- return this;
- }
-
- /**
- * Removes attribute with given name. If element doesn't have attribute with given name nothing
- * will be done.
- *
- * @param name name of attribute which should be removed from element
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when name parameter is {@code null}
- */
- public Element removeAttribute(String name) {
- checkNotRemoved();
- final Attribute attribute = getAttribute(name);
- if (attribute != null) {
- xmlTree.removeAttribute(attribute);
- delegate.getAttributes().removeNamedItem(name);
- }
- return this;
- }
-
- /**
- * Returns {@code true} if element has attribute with given name
- *
- * @param name name of attribute to check
- * @return {@code true} if element has attribute with {@code name} otherwise {@code false}
- * @throws XMLTreeException when this element has been removed from xml tree
- */
- public boolean hasAttribute(String name) {
- checkNotRemoved();
- return delegate.hasAttribute(name);
- }
-
- /**
- * Returns {@code true} if element doesn't have closing tag i.e {@literal }, otherwise {@code false}
- */
- public boolean isVoid() {
- return start.equals(end);
- }
-
- /**
- * Returns attribute with given name or {@code null} if element doesn't have such attribute
- *
- * @param name name to search attribute
- * @return attribute with {@code name} or {@code null} if nothing found
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when name parameter is {@code null}
- */
- public Attribute getAttribute(String name) {
- checkNotRemoved();
- requireNonNull(name, "Non-null new attribute name required.");
- if (delegate.hasAttributes()) {
- return asAttribute(getAttributeNode(name));
- }
- return null;
- }
-
- /**
- * Replaces this element with new one.
- *
- * @param newElement new element which is replacement for current element
- * @return newly created element
- * @throws XMLTreeException when this element has been removed from xml tree or this element is
- * root element
- * @throws NullPointerException when newElement parameter is {@code null}
- */
- public Element replaceWith(NewElement newElement) {
- checkNotRemoved();
- notPermittedOnRootElement();
- requireNonNull(newElement, "Required not null new element");
- insertAfter(newElement);
- final Element inserted = getNextSibling();
- remove();
- return inserted;
- }
-
- /**
- * Appends new element to the end of children list
- *
- * @param newElement element which will be inserted to the end of children list
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree
- * @throws NullPointerException when newElement parameter is {@code null}
- */
- public Element appendChild(NewElement newElement) {
- checkNotRemoved();
- requireNonNull(newElement, "Required not null new element");
- if (isVoid()) {
- throw new XMLTreeException("Append child is not permitted on void elements");
- }
- final Node newNode = createNode(newElement);
- final Element element = createElement(newNode);
- // append new node into document
- delegate.appendChild(newNode);
- // let tree do dirty job
- xmlTree.appendChild(newElement, element, this);
- return this;
- }
-
- /**
- * Inserts new element after current
- *
- * @param newElement element which will be inserted after current
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree or this element is
- * root element
- * @throws NullPointerException when newElement parameter is {@code null}
- */
- public Element insertAfter(NewElement newElement) {
- checkNotRemoved();
- notPermittedOnRootElement();
- requireNonNull(newElement, "Required not null new element");
- final Node newNode = createNode(newElement);
- final Element element = createElement(newNode);
- // if element has next sibling append child to parent
- // else insert before next sibling
- final Node nextNode = nextElementNode(delegate);
- if (nextNode != null) {
- delegate.getParentNode().insertBefore(newNode, nextNode);
- } else {
- delegate.getParentNode().appendChild(newNode);
- }
- // let tree do dirty job
- xmlTree.insertAfter(newElement, element, this);
- return this;
- }
-
- /**
- * Inserts new element before current element
- *
- * @param newElement element which will be inserted before current
- * @return this element instance
- * @throws XMLTreeException when this element has been removed from xml tree or this element is
- * root element
- * @throws NullPointerException when newElement parameter is {@code null}
- */
- public Element insertBefore(NewElement newElement) {
- checkNotRemoved();
- notPermittedOnRootElement();
- requireNonNull(newElement, "Required not null new element");
- // if element has previous sibling insert new element after it
- // inserting before this element to let existing comments
- // or whatever over referenced element
- if (previousElementNode(delegate) != null) {
- getPreviousSibling().insertAfter(newElement);
- return this;
- }
- final Node newNode = createNode(newElement);
- final Element element = createElement(newNode);
- delegate.getParentNode().insertBefore(newNode, delegate);
- // let tree do dirty job
- xmlTree.insertAfterParent(newElement, element, getParent());
- return this;
- }
-
- /**
- * Adds new element as child to the specified by {@link XMLTreeLocation} location.
- *
- *
If it is not possible to insert element in specified location then {@link XMLTreeException}
- * will be thrown
- *
- * @param child new child
- */
- public Element insertChild(NewElement child, XMLTreeLocation place) {
- place.evalInsert(this, child);
- return this;
- }
-
- void setAttributeValue(Attribute attribute) {
- checkNotRemoved();
- final Node attributeNode = getAttributeNode(attribute.getName());
- xmlTree.updateAttributeValue(attribute, attributeNode.getNodeValue());
- getAttributeNode(attribute.getName()).setNodeValue(attribute.getValue());
- }
-
- private void removeTextNodes() {
- final NodeList childNodes = delegate.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++) {
- if (childNodes.item(i).getNodeType() == TEXT_NODE) {
- delegate.removeChild(childNodes.item(i));
- }
- }
- }
-
- private Attribute asAttribute(Node node) {
- if (node == null) {
- return null;
- }
- return new Attribute(this, node.getNodeName(), node.getNodeValue());
- }
-
- private String fetchText() {
- final StringBuilder sb = new StringBuilder();
- final NodeList childNodes = delegate.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++) {
- if (childNodes.item(i).getNodeType() == TEXT_NODE) {
- sb.append(childNodes.item(i).getTextContent());
- }
- }
- return sb.toString();
- }
-
- private Attr createAttrNode(NewAttribute newAttribute) {
- final Attr attr = document().createAttribute(newAttribute.getName());
- attr.setValue(newAttribute.getValue());
- return attr;
- }
-
- private Attr createAttrNSNode(NewAttribute attribute) {
- if (attribute.getPrefix().equals(XMLNS_ATTRIBUTE)) {
- final Attr attr = document().createAttributeNS(XMLNS_ATTRIBUTE_NS_URI, attribute.getName());
- attr.setValue(attribute.getValue());
- // save uri
- xmlTree.putNamespace(attribute.getLocalName(), attribute.getValue());
- return attr;
- } else {
- // retrieve namespace
- final String uri = xmlTree.getNamespaceUri(attribute.getPrefix());
- final Attr attr = document().createAttributeNS(uri, attribute.getName());
- attr.setValue(attribute.getValue());
- return attr;
- }
- }
-
- private Node nextElementNode(Node node) {
- node = node.getNextSibling();
- while (node != null && node.getNodeType() != ELEMENT_NODE) {
- node = node.getNextSibling();
- }
- return node;
- }
-
- private Node previousElementNode(Node node) {
- node = node.getPreviousSibling();
- while (node != null && node.getNodeType() != ELEMENT_NODE) {
- node = node.getPreviousSibling();
- }
- return node;
- }
-
- private void notPermittedOnRootElement() {
- if (!hasParent()) {
- throw new XMLTreeException("Operation not permitted for root element");
- }
- }
-
- private void checkNotRemoved() {
- if (delegate == null) {
- throw new XMLTreeException(
- "Operation not permitted for element which has been removed from XMLTree");
- }
- }
-
- private Element createElement(Node node) {
- final Element element = new Element(xmlTree);
- element.delegate = (org.w3c.dom.Element) node;
- node.setUserData("element", element, null);
- if (node.hasChildNodes()) {
- final NodeList children = node.getChildNodes();
- for (int i = 0; i < children.getLength(); i++) {
- if (children.item(i).getNodeType() == ELEMENT_NODE) {
- createElement(children.item(i));
- }
- }
- }
- return element;
- }
-
- private Node createNode(NewElement newElement) {
- final org.w3c.dom.Element newNode;
- if (newElement.hasPrefix()) {
- final String uri = xmlTree.getNamespaceUri(newElement.getPrefix());
- newNode = document().createElementNS(uri, newElement.getName());
- } else {
- newNode = document().createElement(newElement.getLocalName());
- }
- newNode.setTextContent(newElement.getText());
- // creating all related children
- for (NewElement child : newElement.getChildren()) {
- newNode.appendChild(createNode(child));
- }
- // creating all related attributes
- for (NewAttribute attribute : newElement.getAttributes()) {
- if (attribute.hasPrefix()) {
- newNode.setAttributeNodeNS(createAttrNSNode(attribute));
- } else {
- newNode.setAttributeNode(createAttrNode(attribute));
- }
- }
- return newNode;
- }
-
- private Document document() {
- return delegate.getOwnerDocument();
- }
-
- private Node getAttributeNode(String name) {
- final NamedNodeMap attributes = delegate.getAttributes();
- for (int i = 0; i < attributes.getLength(); i++) {
- if (attributes.item(i).getNodeName().equals(name)) {
- return attributes.item(i);
- }
- }
- return null;
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/ElementMapper.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/ElementMapper.java
deleted file mode 100644
index 10b40e173d..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/ElementMapper.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-/** @author Eugene Voevodin */
-public interface ElementMapper {
-
- T map(Element element);
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/NewAttribute.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/NewAttribute.java
deleted file mode 100644
index 8397319720..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/NewAttribute.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-/**
- * Describes new attribute. Should be used to insert new attribute into existing tree element or may
- * be a part of {@link NewElement}.
- *
- * @author Eugene Voevodin
- */
-public final class NewAttribute extends QName {
-
- private String value;
-
- public NewAttribute(String qName, String value) {
- super(qName);
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
-
- public String asString() {
- return getName() + '=' + '"' + value + '"';
- }
-
- @Override
- public String toString() {
- return asString();
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/NewElement.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/NewElement.java
deleted file mode 100644
index 780a167c24..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/NewElement.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-import static java.util.Arrays.asList;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.tabulate;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Used to add new element to {@link XMLTree}.
- *
- *
This class is really convenient for complex tree updates. To do it you need to make hierarchy
- * from NewElement instances which can contain NewAttribute instances or text as well. When {@link
- * NewElement} instance is ready tree uses {@link NewElement#asString()} to get view of new element.
- *
- *
Why don't we just create {@link Element} instead of using {@link NewElement} class?
- *
- *
- *
First reason - is performance! Each time when you need to insert element tree bytes should
- * be rewrote, but with {@link NewElement} tree bytes will be updated only time
- *
Second reason is - data redundancy! Element should keep values such as children,
- * attributes, name, text for each element instance which will be added to tree and after tree
- * update this values must be dropped because element delegates for {@link org.w3c.dom.Node}
- * and doesn't need it anymore.
- *
Third reason is - tree integrity! Element instance created with tree should be inserted
- * into same tree, so each time when update is going we need to make a lot of checks to save
- * tree elements integrity
- *
- *
- * @author Eugene Voevodin
- */
-public final class NewElement extends QName {
-
- public static NewElement createElement(String name) {
- return new NewElement(name, null);
- }
-
- public static NewElement createElement(String name, String text) {
- return new NewElement(name, text);
- }
-
- public static NewElement createElement(String name, NewElement... children) {
- final NewElement newElement = createElement(name);
- newElement.children = new ArrayList<>(asList(children));
- return newElement;
- }
-
- private String text;
- private List attributes;
- private List children;
-
- private NewElement(String name, String text) {
- super(name);
- this.text = text;
- }
-
- public NewElement setText(String text) {
- this.text = text;
- return this;
- }
-
- public NewElement setAttributes(List attributes) {
- this.attributes = attributes;
- return this;
- }
-
- public NewElement setChildren(List children) {
- this.children = children;
- return this;
- }
-
- public NewElement appendChild(NewElement child) {
- getChildren().add(child);
- return this;
- }
-
- public NewElement setAttribute(String name, String value) {
- getAttributes().add(new NewAttribute(name, value));
- return this;
- }
-
- public String getText() {
- return text == null ? "" : text;
- }
-
- public List getAttributes() {
- if (attributes == null) {
- attributes = new LinkedList<>();
- }
- return attributes;
- }
-
- public List getChildren() {
- if (children == null) {
- children = new LinkedList<>();
- }
- return children;
- }
-
- public boolean hasChildren() {
- return children != null && !children.isEmpty();
- }
-
- public boolean isVoid() {
- return text == null && !hasChildren();
- }
-
- public String asString() {
- final StringBuilder builder = new StringBuilder();
- builder.append('<').append(getName());
- if (attributes != null) {
- for (NewAttribute attribute : attributes) {
- builder.append(' ').append(attribute.asString());
- }
- }
- // if it is void element such as
- if (isVoid()) {
- return builder.append('/').append('>').toString();
- }
- builder.append('>').append(getText());
- if (hasChildren()) {
- builder.append('\n');
- for (NewElement child : children) {
- builder.append(tabulate(child.asString(), 1)).append('\n');
- }
- }
- builder.append('<').append('/').append(getName()).append('>');
- return builder.toString();
- }
-
- @Override
- public String toString() {
- return asString();
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/QName.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/QName.java
deleted file mode 100644
index 4f16c11af2..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/QName.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-/**
- * Describes qualified name
- *
- * @author Eugene Voevodin
- */
-public class QName {
-
- private String prefix;
- private String localName;
-
- public QName(String name) {
- applyName(name);
- }
-
- public String getPrefix() {
- return prefix;
- }
-
- public String getLocalName() {
- return localName;
- }
-
- public String getName() {
- return hasPrefix() ? prefix + ':' + localName : localName;
- }
-
- public boolean hasPrefix() {
- return prefix != null && !prefix.isEmpty();
- }
-
- private void applyName(String newName) {
- final int separator = newName.indexOf(':');
- if (separator != -1) {
- localName = newName.substring(separator + 1);
- prefix = newName.substring(0, separator);
- } else {
- localName = newName;
- }
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/QuietXmlErrorHandler.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/QuietXmlErrorHandler.java
deleted file mode 100644
index e5929e15f8..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/QuietXmlErrorHandler.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-/**
- * The handler is designed for using at xml document parsing and logs messages at the DEBUG level
- * only.
- *
- * @author Roman Nikitenko
- */
-public class QuietXmlErrorHandler implements ErrorHandler {
- private static final Logger LOG = LoggerFactory.getLogger(QuietXmlErrorHandler.class);
-
- @Override
- public void warning(SAXParseException exception) throws SAXException {
- LOG.debug("Warning at parsing xml document: " + exception.getLocalizedMessage(), exception);
- }
-
- @Override
- public void error(SAXParseException exception) throws SAXException {
- LOG.debug("Error at parsing xml document: " + exception.getLocalizedMessage(), exception);
- }
-
- @Override
- public void fatalError(SAXParseException exception) throws SAXException {
- LOG.debug("Fatal error at parsing xml document: " + exception.getLocalizedMessage(), exception);
- throw exception;
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTree.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTree.java
deleted file mode 100644
index 1b146c11b1..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTree.java
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-import static com.google.common.collect.Maps.newHashMapWithExpectedSize;
-import static com.google.common.io.ByteStreams.toByteArray;
-import static java.nio.file.Files.readAllBytes;
-import static java.util.Objects.requireNonNull;
-import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING;
-import static javax.xml.XMLConstants.XML_NS_URI;
-import static javax.xml.stream.XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES;
-import static javax.xml.stream.XMLInputFactory.SUPPORT_DTD;
-import static javax.xml.stream.XMLStreamConstants.CHARACTERS;
-import static javax.xml.stream.XMLStreamConstants.COMMENT;
-import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
-import static javax.xml.stream.XMLStreamConstants.PROCESSING_INSTRUCTION;
-import static javax.xml.stream.XMLStreamConstants.SPACE;
-import static javax.xml.stream.XMLStreamConstants.START_DOCUMENT;
-import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
-import static javax.xml.xpath.XPathConstants.NODESET;
-import static javax.xml.xpath.XPathConstants.STRING;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.SPACES_IN_TAB;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.UTF_8;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.asElement;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.asElements;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.closeTagLength;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.indexOf;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.indexOfAttributeName;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.insertBetween;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.insertInto;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.lastIndexOf;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.level;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.openTagLength;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.replaceAll;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.rootStart;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.single;
-import static org.eclipse.che.commons.xml.XMLTreeUtil.tabulate;
-import static org.w3c.dom.Node.CDATA_SECTION_NODE;
-import static org.w3c.dom.Node.TEXT_NODE;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import javax.xml.namespace.QName;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.stream.XMLInputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-import javax.xml.xpath.XPathFactoryConfigurationException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * XML tool which provides abilities to modify and search information in xml document without
- * affecting of existing formatting, comments.
- *
- *
XMLTree delegates out of the box implementation of org.w3c.dom and provides a lot of
- * functionality such as XPath selection. How does the XMLTree let content in required state? The
- * main idea is simple: know XML elements positions! If we know elements positions and source bytes
- * we can easily manipulate content as we want. So each time when client updates tree, tree rewrites
- * source bytes with new information, indexes new elements, updates delegated document, shifts
- * needed existed elements positions. As you may see there are a lot of data manipulations when
- * update is going, so you should not use this tool for parsing huge xml documents or for often
- * complex updates.
- *
- *
XPath is embedded to XMLTree so each query to tree is xpath query. You will be able to
- * select/update content provided with XMLTree elements or attributes without working with xpath
- * directly.
- *
- *
XMLTree provides methods which do the same as model methods but sometimes they are more
- * convenient, you can use tree methods as well as model methods.
- *
- *
XMLTree disallows using of {@code DOCTYPE} definition in security reasons(XML Entity Expansion
- * injection, XML External Entity Injection).
- *
- *
- *
- * NOTE: XMLTree is not thread-safe!
- *
- * @author Eugene Voevodin
- */
-public final class XMLTree {
-
- /** Creates XMLTree from input stream. Doesn't close the stream */
- public static XMLTree from(InputStream is) throws IOException {
- return new XMLTree(toByteArray(is));
- }
-
- /** Creates XMLTree from file */
- public static XMLTree from(java.io.File file) throws IOException {
- return from(file.toPath());
- }
-
- /** Creates XMLTree from path */
- public static XMLTree from(Path path) throws IOException {
- return new XMLTree(readAllBytes(path));
- }
-
- /** Creates XMLTree from string */
- public static XMLTree from(String xml) {
- return new XMLTree(xml.getBytes(UTF_8));
- }
-
- /** Creates XMLTree from byte array */
- public static XMLTree from(byte[] xml) {
- requireNonNull(xml, "Required not null bytes");
- return new XMLTree(Arrays.copyOf(xml, xml.length));
- }
-
- /** Creates XMLTree with given root element */
- public static XMLTree create(String rootName) {
- return from(String.format(ROOT_TEMPLATE, rootName, rootName));
- }
-
- private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newFactory();
- private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY =
- DocumentBuilderFactory.newInstance();
- private static final XPathFactory XPATH_FACTORY = XPathFactory.newInstance();
- private static final String ROOT_TEMPLATE =
- "\n<%s>\n%s>";
- private static final int EXPECTED_NAMESPACES_SIZE = 2;
-
- /** Factories configuration. */
- static {
- try {
- // Disable doctype declaration to avoid: XML Entity Expansion injection, XML External Entity
- // Injection
- DOCUMENT_BUILDER_FACTORY.setFeature(
- "http://apache.org/xml/features/disallow-doctype-decl", true);
- // Force parser to use secure settings
- DOCUMENT_BUILDER_FACTORY.setFeature(FEATURE_SECURE_PROCESSING, true);
- // Disable usage of entity references to avoid: XML External Entity Injection
- // It is not needed as long as doctype is disabled, but when doctype is enabled
- // this adjustment guarantees avoiding of entity references expansion
- DOCUMENT_BUILDER_FACTORY.setExpandEntityReferences(false);
-
- // Force xpath factory to use secure settings
- XPATH_FACTORY.setFeature(FEATURE_SECURE_PROCESSING, true);
-
- // Disable DTD support at all to avoid: XML Entity Expansion injection, XML External Entity
- // Injection
- XML_INPUT_FACTORY.setProperty(SUPPORT_DTD, false);
- // Disable usage of external entities to avoid: XML External Entity Injection
- XML_INPUT_FACTORY.setProperty(IS_SUPPORTING_EXTERNAL_ENTITIES, false);
- } catch (ParserConfigurationException | XPathFactoryConfigurationException confEx) {
- throw XMLTreeException.wrap(confEx);
- }
- }
-
- private Document document;
- private Map namespaces;
- private List elements;
- private byte[] xml;
-
- private XMLTree(byte[] xml) {
- if (xml.length == 0) {
- throw new XMLTreeException("Source content is empty");
- }
- elements = new LinkedList<>();
- namespaces = newHashMapWithExpectedSize(EXPECTED_NAMESPACES_SIZE);
- this.xml = normalizeLineEndings(xml);
- // reason: parser is going to replace all '\r\n' sequences with single '\n'
- // which will affect elements position in source xml and produce incorrect XMLTree behaviour
- // it comes from spec http://www.w3.org/TR/2004/REC-xml11-20040204/
- document = parseQuietly(this.xml);
- constructTreeQuietly();
- }
-
- /**
- * Searches for requested element text. If there are more then only element were found {@link
- * XMLTreeException} will be thrown
- *
- * @param expression xpath expression to search element
- * @return requested element text
- * @see Element#getText()
- */
- public String getSingleText(String expression) {
- return (String) evaluateXPath(expression, STRING);
- }
-
- /**
- * Searches for requested elements text. If there are no elements were found empty list will be
- * returned.
- *
- *
You can use this method to request not only elements text but for selecting attributes
- * values or whatever text information which is able to be selected with xpath
- *
- * @param expression xpath expression to search elements
- * @return list of elements text or empty list if nothing found
- */
- public List getText(String expression) {
- return retrieveText(expression);
- }
-
- /**
- * Searches for requested elements.
- *
- * @param expression xpath expression to search elements
- * @return list of found elements or empty list if elements were not found
- */
- public List getElements(String expression) {
- final NodeList nodes = (NodeList) evaluateXPath(expression, NODESET);
- return asElements(nodes);
- }
-
- public List getElements(String expression, ElementMapper extends R> mapper) {
- final NodeList nodes = (NodeList) evaluateXPath(expression, NODESET);
- return asElements(nodes, mapper);
- }
-
- /** Returns root element for current tree */
- public Element getRoot() {
- return asElement(document.getDocumentElement());
- }
-
- /**
- * If there are more then only element or nothing were found {@link XMLTreeException} will be
- * thrown
- *
- * @param expression xpath expression to search element
- * @return found element
- */
- public Element getSingleElement(String expression) {
- return single(getElements(expression));
- }
-
- /**
- * Updates requested element text. XPath expression should be used only for element not for
- * attribute or something else. If there are more then only element were found {@link
- * XMLTreeException} will be thrown
- *
- * @param expression xpath expression to search element
- * @param newContent new element text content
- * @see Element#setText(String)
- */
- public void updateText(String expression, String newContent) {
- getSingleElement(expression).setText(newContent);
- }
-
- /**
- * Adds element to the end of the list of existed children or adds it as only child.
- *
- *
If there are more then only parent element were found {@link XMLTreeException} will be
- * thrown
- *
- * @param expression xpath expression to search parent
- * @param newElement new element which will be inserted. It should be created with same tree
- * instance
- */
- public void appendChild(String expression, NewElement newElement) {
- single(getElements(expression)).appendChild(newElement);
- }
-
- /**
- * Inserts element before referenced one. All comments related before referenced element going to
- * have same positions like they had before.
- *
- *
If there are more then only referenced element were found {@link XMLTreeException} will be
- * thrown
- *
- * @param expression xpath expression to search referenced element
- * @param newElement new element which will be inserted. It should be created with same tree
- * instance
- */
- public void insertBefore(String expression, NewElement newElement) {
- single(getElements(expression)).insertBefore(newElement);
- }
-
- /**
- * Inserts element after referenced one.
- *
- *
If there are more then only referenced elements were found {@link XMLTreeException} will be
- * thrown
- *
- * @param expression xpath expression to search referenced element
- * @param newElement new element which will be inserted. It should be created with same tree
- * instance
- */
- public void insertAfter(String expression, NewElement newElement) {
- single(getElements(expression)).insertAfter(newElement);
- }
-
- /**
- * Removes requested element. If there are was any text before removal element it will be
- * removed as well. It is important when we need to keep formatting pretty - if it was pretty. It
- * is really strange when parent element contains not only whitespaces but another text content.
- *
- *
If there are more then only referenced element were found {@link XMLTreeException} will be
- * thrown
- *
- * @param expression xpath expression to remove element
- */
- public void removeElement(String expression) {
- single(getElements(expression)).remove();
- }
-
- /** Returns copy of source bytes. TODO: write replacement explanation */
- public byte[] getBytes() {
- final String separator = System.getProperty("line.separator");
- if (!"\n".equals(separator)) {
- return replaceAll(xml, "\n".getBytes(), separator.getBytes());
- }
- return Arrays.copyOf(xml, xml.length);
- }
-
- /** Writes copy of source bytes to output stream. Doesn't close the stream */
- public void writeTo(OutputStream outputStream) throws IOException {
- outputStream.write(getBytes());
- }
-
- /** Writes source bytes to path */
- public void writeTo(Path path) throws IOException {
- Files.write(path, getBytes());
- }
-
- /** Writes source bytes to file */
- public void writeTo(java.io.File file) throws IOException {
- Files.write(file.toPath(), getBytes());
- }
-
- /**
- * Evaluates xpath expression with given return type. Rethrows all exceptions as {@link
- * XMLTreeException}
- */
- @SuppressWarnings("unchecked")
- private Object evaluateXPath(String expression, QName returnType) {
- final XPath xpath = XPATH_FACTORY.newXPath();
- try {
- return xpath.evaluate(expression, document, returnType);
- } catch (XPathExpressionException xpathEx) {
- throw XMLTreeException.wrap(xpathEx);
- }
- }
-
- /**
- * Parses document using {@link DocumentBuilder} Rethrows all exceptions as {@link
- * XMLTreeException}
- */
- private Document parseQuietly(byte[] xml) {
- try {
- final DocumentBuilder db = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
- db.setErrorHandler(new QuietXmlErrorHandler());
- return db.parse(new ByteArrayInputStream(xml));
- } catch (Exception ex) {
- throw XMLTreeException.wrap(ex);
- }
- }
-
- /**
- * Evaluates xpath expression and maps result as list of strings using {@link
- * Node#getTextContent()} method
- */
- private List retrieveText(String expression) {
- final NodeList nodeList = (NodeList) evaluateXPath(expression, NODESET);
- final List elementsText = new ArrayList<>(nodeList.getLength());
- for (int i = 0; i < nodeList.getLength(); i++) {
- elementsText.add(nodeList.item(i).getTextContent());
- }
- return elementsText;
- }
-
- /**
- * Constructs tree based on segments which are supplied by {@link XMLStreamReader}. Before this
- * method is invoked {@link #document} should be initialized first. For START_ELEMENT,
- * END_ELEMENT, CHARACTERS reader provides offset from start of source array bytes, so we can
- * fetch position of elements and text. Each created element associated with related {@link Node}
- * and vise-versa.
- */
- private void constructTree() throws XMLStreamException {
- final XMLStreamReader reader = newXMLStreamReader();
- final LinkedList stack = new LinkedList<>();
- // before element open tag index
- int beforeStart = rootStart(xml) - 1;
- // used to associate each element with document node
- Node node = document.getDocumentElement();
- // used to hold previous reader event
- int prevEvent = START_DOCUMENT;
- while (reader.hasNext()) {
- switch (reader.next()) {
- case START_ELEMENT:
- final Element newElement = new Element(this);
- newElement.start = new Segment(beforeStart + 1, elementRight(beforeStart + 1, reader));
- // if new node is not xml root - set up relationships
- if (!stack.isEmpty()) {
- node = deepNext(node, true);
- }
- // connect node with element
- node.setUserData("element", newElement, null);
-
- newElement.delegate = safeCast(node);
- // let next event know about its start
- beforeStart = newElement.start.right;
- // if element has declared namespaces register it
- putNamespaces(reader);
- stack.push(newElement);
- break;
- case END_ELEMENT:
- final Element element = stack.pop();
- element.end = new Segment(beforeStart + 1, elementRight(beforeStart + 1, reader));
- elements.add(element);
- beforeStart = element.end.right;
- break;
- case CHARACTERS:
- // characters event may be invoked 2 or more times
- // on the element text, but related node is single text node
- // so the only segment should be created for it
- if (prevEvent == CHARACTERS) continue;
-
- final Element current = stack.peek();
- if (current.text == null) {
- // TODO replace with array list as we know current node 'text nodes' count
- current.text = new LinkedList<>();
- }
-
- final Node nextNode = deepNext(node, true);
-
- final int left = beforeStart + 1;
- final int right = left + textLength(nextNode) - 1;
-
- current.text.add(new Segment(left, right));
- beforeStart = right;
- node = skipTextNodes(nextNode);
- break;
- case COMMENT:
- case SPACE:
- case PROCESSING_INSTRUCTION:
- if (!stack.isEmpty()) {
- node = deepNext(node, true);
- beforeStart = lastIndexOf(xml, '>', reader.getLocation().getCharacterOffset());
- }
- break;
- default:
- // DO NOTHING
- }
- prevEvent = reader.getEventType();
- }
- }
-
- /** Returns length of cdata and text nodes chain. */
- private int textLength(Node node) {
- int length = node.getTextContent().length();
- node = node.getNextSibling();
- while (node != null
- && (node.getNodeType() == TEXT_NODE || node.getNodeType() == CDATA_SECTION_NODE)) {
- length += node.getTextContent().length();
- if (node.getNodeType() == CDATA_SECTION_NODE) {
- length += 12; // - 12
- }
- node = node.getNextSibling();
- }
- return length;
- }
-
- /**
- * Returns safe Element instance for node or throws exception if it is not possible to cast {@code
- * node} to {@link org.w3c.dom.Element}.
- */
- private org.w3c.dom.Element safeCast(Node node) {
- if (!(node instanceof org.w3c.dom.Element)) {
- throw new XMLTreeException("It is not possible to associate xml elements");
- }
- return (org.w3c.dom.Element) node;
- }
-
- /**
- * Returns last text or cdata node in the chain of cdata and text nodes.
- *
- *
i.e. node1 is text node and node1 has next sibling node2 as cdata node
- * and node2 has next sibling node3 as text node and node3 has next sibling
- * node4 as element node, then node3 will be returned as last text node in the
- * chain. Consider following examples:
- *
- *
- * 1.
- * node3 - last text node
- *
- * text cdata text element
- * node1 -> node2 -> node3 -> node4
- *
- * 2.
- * node2 - last text result
- *
- * text cdata
- * node1 -> node2 -> null
- *
- *
- */
- private Node skipTextNodes(Node node) {
- final Node next = node.getNextSibling();
- if (next != null
- && (next.getNodeType() == CDATA_SECTION_NODE || next.getNodeType() == TEXT_NODE)) {
- return skipTextNodes(next);
- }
- return node;
- }
-
- /**
- * Searches for the element start right bound index. TODO respect element attributes text content
- * while checking '<'
- */
- private int elementRight(int left, XMLStreamReader reader) {
- int rightIdx = lastIndexOf(xml, '>', reader.getLocation().getCharacterOffset());
- int leftIdx = lastIndexOf(xml, '<', rightIdx);
- while (leftIdx > left) {
- rightIdx = lastIndexOf(xml, '>', rightIdx - 1);
- leftIdx = lastIndexOf(xml, '<', rightIdx);
- }
- return rightIdx;
- }
-
- private Node deepNext(Node node, boolean deep) {
- if (deep && node.getChildNodes().getLength() != 0) {
- return node.getFirstChild();
- }
- final Node next = node.getNextSibling();
- if (next != null) {
- return next;
- } else if (node == document.getDocumentElement()) {
- return node;
- }
- return deepNext(node.getParentNode(), false);
- }
-
- /**
- * Same as {@link #constructTree()}, only difference that it wraps {@link XMLStreamException} to
- * {@link XMLTreeException}
- */
- private void constructTreeQuietly() {
- try {
- constructTree();
- } catch (XMLStreamException xmlEx) {
- throw XMLTreeException.wrap(xmlEx);
- }
- }
-
- /** Should be invoked on ELEMENT_START event */
- private void putNamespaces(XMLStreamReader reader) {
- for (int i = 0; i < reader.getNamespaceCount(); i++) {
- final String prefix = reader.getNamespacePrefix(i);
- if (prefix != null) {
- putNamespace(prefix, reader.getNamespaceURI(i));
- }
- }
- }
-
- /** Creates new stream reader instance */
- private XMLStreamReader newXMLStreamReader() {
- try {
- return XML_INPUT_FACTORY.createXMLStreamReader(new ByteArrayInputStream(xml), "UTF-8");
- } catch (Exception xmlEx) {
- throw XMLTreeException.wrap(xmlEx);
- }
- }
-
- /**
- * Updates element text content. Update based on element text segments. If element doesn't have
- * any text segment then new segment will be created which positions based on container bounds,
- * otherwise only first text segment will be used for update, other text segments will be removed.
- */
- void updateText(Element target) {
- // it may be null when target element doesn't contain
- // text so CHARACTERS event was not processed
- if (target.text == null) {
- target.text = new LinkedList<>();
- // updateSegmentContent will set up right bound
- target.text.add(new Segment(target.start.right + 1, target.start.right));
- }
- final Iterator segIt = target.text.iterator();
- final Segment first = segIt.next();
- // removing all segments instead of first
- while (segIt.hasNext()) {
- final Segment removal = segIt.next();
- segIt.remove();
- removeSegment(removal);
- }
- updateSegmentContent(first, target.getText());
- }
-
- void updateAttributeValue(Attribute attribute, String oldValue) {
- final Segment segment = valueSegment(attribute, oldValue);
- updateSegmentContent(segment, attribute.getValue());
- }
-
- /** Adds new element to the end of children list with given parent. */
- void appendChild(NewElement newElement, Element relatedToNew, Element parent) {
- final int level = level(parent) + 1;
- final int lengthBefore = xml.length;
- final int insertHere = lastIndexOf(xml, '>', parent.end.left) + 1;
- // inserting new element bytes to tree bytes
- xml = insertInto(xml, insertHere, '\n' + tabulate(newElement.asString(), level));
- // shift existing segments which are after parent start
- shiftSegments(insertHere, xml.length - lengthBefore);
- // create and set up start, end, text segments to created element
- applySegments(newElement, relatedToNew, insertHere - 1, level);
- // let tree know about added element
- registerElement(relatedToNew);
- }
-
- /** Inserts element after referenced one */
- void insertAfter(NewElement newElement, Element relatedToNew, Element refElement) {
- final int level = level(refElement);
- final int lengthBefore = xml.length;
- // inserting new element bytes to tree bytes
- xml = insertInto(xml, refElement.end.right + 1, '\n' + tabulate(newElement.asString(), level));
- // shift existing segments which are after parent start
- shiftSegments(refElement.end.right, xml.length - lengthBefore);
- // create and set up start, end, text segments to created element
- // +1 because of \n
- applySegments(newElement, relatedToNew, refElement.end.right, level);
- // let tree know about inserted element
- registerElement(relatedToNew);
- }
-
- /**
- * Inserts element before referenced one. It is important to let all related to {@code refElement}
- * comments on their places, so to avoid deformation we inserting new element after previous
- * sibling or after element parent if element doesn't have previous sibling
- */
- void insertAfterParent(NewElement newElement, Element relatedToNew, Element parent) {
- final int level = level(parent) + 1;
- final int lengthBefore = xml.length;
- // inserting after parent
- xml = insertInto(xml, parent.start.right + 1, '\n' + tabulate(newElement.asString(), level));
- // shift existing segments which are after parent start
- shiftSegments(parent.start.right, xml.length - lengthBefore);
- // create and set up start, end, text segments to created element
- applySegments(newElement, relatedToNew, parent.start.right, level);
- // let tree know about inserted element
- registerElement(relatedToNew);
- }
-
- /**
- * Removes element bytes from tree.
- *
- *
It is important to save xml tree pretty view, so element should be removed without of
- * destroying style of xml document.
- *
- *
- * e.g.
- *
- * {@literal }
- * {@literal } {@literal +\n}
- * {@literal } {@literal \n}
- * {@literal }
- *
- * first + is before left border
- * last + is before right border
- *
- * segment [first, last] - will be removed
- *
- *
- * So after removing - formatting will be the same. We can't remove just element from start to end
- * because it will produce not pretty formatting for good and pretty formatted before document.
- */
- void removeElement(Element element) {
- final int leftBound = lastIndexOf(xml, '>', element.start.left) + 1;
- final int lengthBefore = xml.length;
- // if text segment before removal element
- // exists it should go to hell with removal
- if (leftBound != element.start.left - 1) {
- removeSegmentFromElement(element.getParent(), leftBound);
- }
- // replacing content with nothing
- xml = insertBetween(xml, leftBound, element.end.right, "");
- // shift all elements which are right from removed element
- shiftSegments(element.end.right, xml.length - lengthBefore);
- // let tree know that element is not a family member
- unregisterElement(element);
- }
-
- /** Inserts new attribute value content to tree bytes */
- void insertAttribute(NewAttribute attribute, Element owner) {
- final int len = xml.length;
- // inserting new attribute content
- xml = insertInto(xml, owner.start.right, ' ' + attribute.asString());
- // shift all elements which are right from removed element
- shiftSegments(owner.start.left - 1, xml.length - len);
- }
-
- /** Removes element bytes from tree */
- void removeAttribute(Attribute attribute) {
- final Element element = attribute.getElement();
- final int lengthBefore = xml.length;
- final Segment segment = attributeSegment(attribute);
- // replacing attribute segment with nothing
- xml = insertBetween(xml, segment.left - 1, segment.right, "");
- // shift all elements which are left from owner left
- shiftSegments(element.start.left, xml.length - lengthBefore);
- }
-
- // TODO should it be public?
- void putNamespace(String prefix, String uri) {
- namespaces.put(prefix, uri);
- }
-
- // TODO should it be public?
- String getNamespaceUri(String prefix) {
- final String uri = namespaces.get(prefix);
- return uri == null ? XML_NS_URI : uri;
- }
-
- /**
- * Shift given segment on offset if it is righter then idx
- *
- * @param segment segment to shift
- * @param leftBound left bound
- * @param offset offset to shift on, it can be negative
- */
- private void shiftSegment(Segment segment, int leftBound, int offset) {
- if (segment.left > leftBound) {
- segment.left += offset;
- segment.right += offset;
- }
- }
-
- /** Removes segment which left bound equal to {@param left} from element */
- private void removeSegmentFromElement(Element element, int left) {
- for (Iterator segIt = element.text.iterator(); segIt.hasNext(); ) {
- if (segIt.next().left == left) {
- segIt.remove();
- break;
- }
- }
- }
-
- /** Iterates all existed elements and shifts their segments if needed */
- private void shiftSegments(int fromIdx, int offset) {
- for (Element element : elements) {
- if (element.end.left > fromIdx) {
- shiftSegment(element.start, fromIdx, offset);
- shiftSegment(element.end, fromIdx, offset);
- if (element.text != null) {
- for (Segment textSegment : element.text) {
- shiftSegment(textSegment, fromIdx, offset);
- }
- }
- }
- }
- }
-
- /**
- * Removes given segment from source bytes and shifts segments left on offset equal to removal
- * segment length
- */
- private void removeSegment(Segment segment) {
- final int lengthBefore = xml.length;
- xml = insertBetween(xml, segment.left, segment.right, "");
- shiftSegments(segment.left, xml.length - lengthBefore);
- }
-
- /**
- * Inserts content bytes between left and right segment bounds and shifts segments on offset equal
- * to difference between new and old source bytes length
- */
- private void updateSegmentContent(Segment segment, String content) {
- final int lengthBefore = xml.length;
- xml = insertBetween(xml, segment.left, segment.right, content);
- shiftSegments(segment.left, xml.length - lengthBefore);
- segment.right = segment.left + content.length() - 1;
- }
-
- /** Adds element and it children to tree */
- private void registerElement(Element element) {
- elements.add(element);
- for (Element child : element.getChildren()) {
- registerElement(child);
- }
- }
-
- /** Removes element and children from tree */
- private void unregisterElement(Element element) {
- elements.remove(element);
- for (Element child : element.getChildren()) {
- unregisterElement(child);
- }
- }
-
- /** Retrieves attribute segment */
- private Segment attributeSegment(Attribute attribute) {
- final Element owner = attribute.getElement();
-
- final byte[] name = attribute.getName().getBytes();
- final byte[] value = attribute.getValue().getBytes();
-
- final int attrLeft =
- indexOfAttributeName(xml, name, owner.start.left + owner.getName().length());
- final int valueLeft = indexOf(xml, value, attrLeft + name.length);
-
- return new Segment(attrLeft, valueLeft + value.length);
- }
-
- /** Retrieves attribute value segment */
- private Segment valueSegment(Attribute attribute, String oldValue) {
- final Element owner = attribute.getElement();
-
- final byte[] name = attribute.getName().getBytes();
- final byte[] value = oldValue.getBytes();
-
- final int attrLeft =
- indexOfAttributeName(xml, name, owner.start.left + owner.getName().length());
- final int valueLeft = indexOf(xml, value, attrLeft + name.length);
-
- return new Segment(valueLeft, valueLeft + value.length - 1);
- }
-
- /** Creates segments for newly created element and related children */
- private int applySegments(
- NewElement newElement, Element relatedToNew, int prevElementCloseRight, int level) {
- // text length before element
- // child - new element
- // '+' - text before element
- //
- // \n
- // ++++...
- final int levelTextLength = level * SPACES_IN_TAB;
-
- // '*' - before element open tag pos
- //
- // | prevElementCloseRight
- // v
- // \n *...
- // +1 because of '\n'
- final int beforeOpenLeft = 1 + prevElementCloseRight + levelTextLength;
-
- // we should add text segment which
- // is before new element to the parent text segments and start to track it
- final Element parent = relatedToNew.getParent();
- if (parent.text == null) {
- parent.text = new LinkedList<>();
- }
- parent.text.add(new Segment(prevElementCloseRight + 1, beforeOpenLeft));
-
- // pos of open tag right '>'
- final int openRight = beforeOpenLeft + openTagLength(newElement);
-
- relatedToNew.start = new Segment(beforeOpenLeft + 1, openRight);
- // if element is void it doesn't have children and text
- // and it has same start and end so we can initialize
- // only start and end segments
- if (relatedToNew.isVoid()) {
- relatedToNew.end = relatedToNew.start;
- return openRight;
- }
- // if element has children it doesn't have text instead of
- // whitespaces, so all what we need - detect element close tag segment
- // to do so we need to map segments for all children first
- int childRight = openRight;
- if (newElement.hasChildren()) {
-
- final Iterator newChIt = newElement.getChildren().iterator();
- final Iterator chIt = relatedToNew.getChildren().iterator();
-
- while (newChIt.hasNext()) {
- childRight = applySegments(newChIt.next(), chIt.next(), childRight, level + 1);
- }
- } else {
- relatedToNew.text = new LinkedList<>();
- }
- // before element close tag pos
- // +
- // \n text
- int beforeCloseLeft;
- if (newElement.hasChildren()) {
- beforeCloseLeft = childRight + levelTextLength + 1;
- } else {
- beforeCloseLeft = childRight + newElement.getText().length();
- }
- relatedToNew.text.add(new Segment(childRight + 1, beforeCloseLeft));
- relatedToNew.end =
- new Segment(beforeCloseLeft + 1, beforeCloseLeft + closeTagLength(newElement));
- return relatedToNew.end.right;
- }
-
- private byte[] normalizeLineEndings(byte[] src) {
- final String separator = System.getProperty("line.separator");
- // replacing all \r\n with \n
- if (separator.equals("\r\n")) {
- src = replaceAll(src, "\r\n".getBytes(), "\n".getBytes());
- }
- // replacing all \r with \n to prevent combination of \r\n which was created after
- // \r\n replacement, i.e. content \r\r\n after first replacement will be \r\n which is not okay
- return replaceAll(src, "\r".getBytes(), "\n".getBytes());
- }
-
- /** Describes element, attribute or text position in the source array of bytes. */
- static class Segment {
- int left;
- int right;
-
- Segment(int left, int right) {
- this.left = left;
- this.right = right;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == this) {
- return true;
- }
- if (!(obj instanceof Segment)) {
- return false;
- }
- final Segment other = (Segment) obj;
- return other.left == left && other.right == right;
- }
-
- @Override
- public int hashCode() {
- return 31 * left ^ 31 * right;
- }
-
- @Override
- public String toString() {
- return "left: " + left + ", right: " + right;
- }
- }
-
- @Override
- public String toString() {
- return new String(getBytes(), UTF_8);
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeException.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeException.java
deleted file mode 100644
index 0525be0269..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-/** @author Eugene Voevodin */
-public class XMLTreeException extends RuntimeException {
-
- public static XMLTreeException wrap(Exception ex) {
- return new XMLTreeException(ex.getMessage(), ex);
- }
-
- public XMLTreeException(String message) {
- super(message);
- }
-
- public XMLTreeException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeLocation.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeLocation.java
deleted file mode 100644
index 4ba55320c8..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeLocation.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-import java.util.LinkedList;
-
-/**
- * Helps to add new tree elements in specified places
- *
- * @author Eugene Voevodin
- */
-public class XMLTreeLocation {
-
- /** Location which indicates position after element with given name */
- public static XMLTreeLocation after(String name) {
- return new XMLTreeLocation(LocationType.AFTER, name);
- }
-
- /** Location which indicates position before element with given name */
- public static XMLTreeLocation before(String name) {
- return new XMLTreeLocation(LocationType.BEFORE, name);
- }
-
- /** Location which indicates after last element position */
- public static XMLTreeLocation inTheEnd() {
- return new XMLTreeLocation(LocationType.END, "");
- }
-
- /** Location which indicates before first element position */
- public static XMLTreeLocation inTheBegin() {
- return new XMLTreeLocation(LocationType.BEGIN, "");
- }
-
- /** Indicates position after any of elements with given names */
- public static XMLTreeLocation afterAnyOf(String... names) {
- if (names.length == 0) {
- throw new IllegalArgumentException("Required not empty elements names");
- }
- return disjunctionChain(LocationType.AFTER, names);
- }
-
- /** Indicates position before any of elements with given names */
- public static XMLTreeLocation beforeAnyOf(String... names) {
- if (names.length == 0) {
- throw new IllegalArgumentException("Required not empty elements names");
- }
- return disjunctionChain(LocationType.BEFORE, names);
- }
-
- /** Connects locations with same type by {@link #or} connector */
- private static XMLTreeLocation disjunctionChain(LocationType location, String[] names) {
- final XMLTreeLocation treeLocation = new XMLTreeLocation(location, names[0]);
- for (int i = 1; i < names.length; i++) {
- treeLocation.or(new XMLTreeLocation(location, names[i]));
- }
- return treeLocation;
- }
-
- private LinkedList locations;
- private LocationType location;
- private String name;
-
- private XMLTreeLocation(LocationType location, String name) {
- this.location = location;
- this.name = name;
- }
-
- public XMLTreeLocation or(XMLTreeLocation location) {
- locations().add(location);
- return this;
- }
-
- void evalInsert(Element parent, NewElement newElement) {
- locations().addFirst(this);
- for (XMLTreeLocation location : locations) {
- switch (location.location) {
- case AFTER:
- if (parent.hasSingleChild(location.name)) {
- parent.getSingleChild(location.name).insertAfter(newElement);
- return;
- }
- break;
- case BEFORE:
- if (parent.hasSingleChild(location.name)) {
- parent.getSingleChild(location.name).insertBefore(newElement);
- return;
- }
- break;
- case BEGIN:
- final Element first = parent.getFirstChild();
- if (first != null) {
- first.insertBefore(newElement);
- } else {
- parent.appendChild(newElement);
- }
- return;
- case END:
- parent.appendChild(newElement);
- return;
- }
- }
- throw new XMLTreeException("It is not possible to insert element in specified location");
- }
-
- private LinkedList locations() {
- return locations == null ? locations = new LinkedList<>() : locations;
- }
-
- private enum LocationType {
- AFTER,
- BEFORE,
- BEGIN,
- END
- }
-}
diff --git a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeUtil.java b/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeUtil.java
deleted file mode 100644
index ae2d274a92..0000000000
--- a/core/commons/che-core-commons-xml/src/main/java/org/eclipse/che/commons/xml/XMLTreeUtil.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (c) 2012-2018 Red Hat, Inc.
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- */
-package org.eclipse.che.commons.xml;
-
-import static java.lang.Character.isWhitespace;
-import static java.lang.Math.min;
-import static java.lang.System.arraycopy;
-import static java.util.Arrays.fill;
-import static org.w3c.dom.Node.ELEMENT_NODE;
-
-import java.io.ByteArrayOutputStream;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Utils for xml tree
- *
- * @author Eugene Voevodin
- */
-public final class XMLTreeUtil {
-
- public static final Charset UTF_8 = Charset.forName("utf-8");
- public static final int SPACES_IN_TAB = 4;
-
- /**
- *
- *
- *
- *
- * @param src source array
- * @param left left anchor - not included to result
- * @param right right anchor - not included to result
- * @param content content which will be inserted between left and right
- * @return new content
- */
- public static byte[] insertBetween(byte[] src, int left, int right, String content) {
- final byte[] contentSrc = content.getBytes(UTF_8);
- final byte[] newSrc = new byte[left + src.length - right + contentSrc.length - 1];
- arraycopy(src, 0, newSrc, 0, left);
- arraycopy(contentSrc, 0, newSrc, left, contentSrc.length);
- arraycopy(src, right + 1, newSrc, left + contentSrc.length, src.length - right - 1);
- return newSrc;
- }
-
- /**
- *
- *
- *