<commit_before>// Copyright (c) 2003-2012, Jodd Team (jodd.org). All Rights Reserved.

package jodd.lagarto.dom;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * DOM node.
 */
public abstract class Node implements Cloneable {

	/**
	 * Node types.
	 */
	public enum NodeType {
		DOCUMENT, ELEMENT, TEXT, COMMENT, CDATA, DOCUMENT_TYPE, XML_DECLARATION
	}

	protected final String nodeName;
	protected final NodeType nodeType;
	protected final boolean caseSensitive;
	protected String nodeValue;

	protected Node parentNode;
	protected List<Attribute> attributes;

	protected List<Node> childNodes;
	protected int childElementNodesCount;
	protected Node[] childElementNodes;

	protected int siblingIndex;
	protected int siblingElementIndex = -1;
	protected int siblingNameIndex = -1;

	protected int deepLevel;

	protected Node(NodeType nodeType, String nodeName, boolean caseSensitive) {
		this.caseSensitive = caseSensitive;
		this.nodeName = caseSensitive ? nodeName : nodeName.toLowerCase();
		this.nodeType = nodeType;
	}

	// ---------------------------------------------------------------- clone

	/**
	 * Copies all non-final values to the empty cloned object.
	 * Cache-related values are not copied.
	 */
	protected <T extends Node> T cloneTo(T dest) {
//		dest.nodeValue = nodeValue;		// set in clone implementations!
		dest.parentNode = parentNode;
		dest.deepLevel = deepLevel;

		if (attributes != null) {
			dest.attributes = new ArrayList<Attribute>(attributes.size());
			for (Attribute attr : attributes) {
				dest.attributes.add(attr.clone());
			}
		}

		if (childNodes != null) {
			dest.childNodes = new ArrayList<Node>(childNodes.size());
			for (Node node : childNodes) {
				dest.childNodes.add(node.clone());
			}
		}

		return dest;
	}
	
	@Override
	public abstract Node clone();

	// ---------------------------------------------------------------- basic

	/**
	 * Returns {@link NodeType node type}.
	 */
	public NodeType getNodeType() {
		return nodeType;
	}

	/**
	 * Returns node name or <code>null</code> if name is not available.
	 */
	public String getNodeName() {
		return nodeName;
	}

	/**
	 * Returns node value or <code>null</code> if value is not available.
	 */
	public String getNodeValue() {
		return nodeValue;
	}

	/**
	 * Sets node value.
	 */
	public void setNodeValue(String value) {
		this.nodeValue = value;
	}

	// ---------------------------------------------------------------- tree

	/**
	 * Removes this node from DOM tree.
	 */
	public void detachFromParent() {
		if (parentNode == null) {
			return;
		}
		int index = siblingIndex;
		if (parentNode.childNodes != null) {
			parentNode.childNodes.remove(index);
			parentNode.reindexChildren();
		}
		parentNode = null;
		deepLevel = 0;
	}

	/**
	 * Appends child node.
	 */
	public void appendChild(Node node) {
		node.detachFromParent();
		node.parentNode = this;
		node.deepLevel = deepLevel + 1;
		initChildNodes();
		childNodes.add(node);
		reindexChildren();
	}
	
	public void appendChild(Node... nodes) {<commit_msg>clone parent fixed<commit_after>// Copyright (c) 2003-2012, Jodd Team (jodd.org). All Rights Reserved.

package jodd.lagarto.dom;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * DOM node.
 */
public abstract class Node implements Cloneable {

	/**
	 * Node types.
	 */
	public enum NodeType {
		DOCUMENT, ELEMENT, TEXT, COMMENT, CDATA, DOCUMENT_TYPE, XML_DECLARATION
	}

	protected final String nodeName;
	protected final NodeType nodeType;
	protected final boolean caseSensitive;
	protected String nodeValue;

	protected Node parentNode;
	protected List<Attribute> attributes;

	protected List<Node> childNodes;
	protected int childElementNodesCount;
	protected Node[] childElementNodes;

	protected int siblingIndex;
	protected int siblingElementIndex = -1;
	protected int siblingNameIndex = -1;

	protected int deepLevel;

	protected Node(NodeType nodeType, String nodeName, boolean caseSensitive) {
		this.caseSensitive = caseSensitive;
		this.nodeName = caseSensitive ? nodeName : nodeName.toLowerCase();
		this.nodeType = nodeType;
	}

	// ---------------------------------------------------------------- clone

	/**
	 * Copies all non-final values to the empty cloned object.
	 * Cache-related values are not copied.
	 */
	protected <T extends Node> T cloneTo(T dest) {
//		dest.nodeValue = nodeValue;		// already  in clone implementations!
		dest.parentNode = parentNode;
		dest.deepLevel = deepLevel;

		if (attributes != null) {
			dest.attributes = new ArrayList<Attribute>(attributes.size());
			for (Attribute attr : attributes) {
				dest.attributes.add(attr.clone());
			}
		}

		if (childNodes != null) {
			dest.childNodes = new ArrayList<Node>(childNodes.size());
			for (Node child : childNodes) {
				Node childClone = child.clone();

				childClone.parentNode = dest;	// fix parent!
				dest.childNodes.add(childClone);
			}
		}

		return dest;
	}
	
	@Override
	public abstract Node clone();

	// ---------------------------------------------------------------- basic

	/**
	 * Returns {@link NodeType node type}.
	 */
	public NodeType getNodeType() {
		return nodeType;
	}

	/**
	 * Returns node name or <code>null</code> if name is not available.
	 */
	public String getNodeName() {
		return nodeName;
	}

	/**
	 * Returns node value or <code>null</code> if value is not available.
	 */
	public String getNodeValue() {
		return nodeValue;
	}

	/**
	 * Sets node value.
	 */
	public void setNodeValue(String value) {
		this.nodeValue = value;
	}

	// ---------------------------------------------------------------- tree

	/**
	 * Removes this node from DOM tree.
	 */
	public void detachFromParent() {
		if (parentNode == null) {
			return;
		}
		int index = siblingIndex;
		if (parentNode.childNodes != null) {
			parentNode.childNodes.remove(index);
			parentNode.reindexChildren();
		}
		parentNode = null;
		deepLevel = 0;
	}

	/**
	 * Appends child node.
	 */
	public void appendChild(Node node) {
		node.detachFromParent();
		node.parentNode = this;
		node.deepLevel = deepLevel + 1;
		initChildNodes();
		childNodes.add(node);
		reindexChildren();
	}

	/**
	 * Appends several child nodes at once.
	 */
	public void appendChild(Node... nodes) {
{'fraction_non_alphanumeric': 0.16953199617956066, 'fraction_numerical': 0.0038204393505253103, 'mean_word_length': 2.708972845336482, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5703853', 'n_tokens_mistral': 2024, 'n_tokens_neox': 1819, 'n_words': 523}