All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.larssh.json.dom.JsonDomElement Maven / Gradle / Ivy

// Generated by delombok at Tue Jun 11 15:48:59 UTC 2024
package de.larssh.json.dom;

import static de.larssh.utils.Finals.constant;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.TypeInfo;
import de.larssh.json.dom.values.JsonDomValue;
import de.larssh.utils.Finals;
import de.larssh.utils.Nullables;
import de.larssh.utils.text.Patterns;
import de.larssh.utils.text.Strings;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

/**
 * JSON DOM implementation of {@link Element}.
 *
 * @param  implementation specific JSON element type
 */
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.GodClass"})
@SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR", justification = "fields attributes and childNodes are not used from within the constuctor")
public class JsonDomElement extends JsonDomNode implements Element {
	/**
	 * Name of the attribute {@code name}
	 */
	public static final String ATTRIBUTE_NAME = constant("name");
	/**
	 * Name of the attribute {@code type}
	 */
	public static final String ATTRIBUTE_TYPE = constant("type");
	/**
	 * The special value "*" matches all tags.
	 */
	private static final String GET_ELEMENTS_BY_TAG_NAME_WILDCARD = "*";
	/**
	 * Regex character class expression describing the first character of an XML
	 * name following
	 * the
	 * XML 1.1 standard.
	 */
	@SuppressWarnings("checkstyle:AvoidEscapedUnicodeCharacters")
	private static final String XML_NAME_START_CHARACTERS = ":A-Z_a-zÀ-ÖØ-öø-˿Ͱ-ͽͿ-῿‌-‍⁰-↏Ⰰ-⿯、-퟿豈-﷏ﷰ-�";
	/**
	 * Regex character class expression describing the second and following
	 * characters of an XML name following
	 * the
	 * XML 1.1 standard.
	 */
	@SuppressWarnings("checkstyle:AvoidEscapedUnicodeCharacters")
	private static final String XML_NAME_CHARACTERS = XML_NAME_START_CHARACTERS + "-.0-9·̀-ͯ‿-⁀";
	/**
	 * Pattern finding one or more illegal XML characters
	 */
	@SuppressWarnings("checkstyle:MultipleStringLiterals")
	private static final Pattern PATTERN_ILLEGAL_XML_CHARACTERS = Pattern.compile("[^" + XML_NAME_CHARACTERS + "]+");
	/**
	 * Pattern finding one or more illegal XML characters at the start
	 */
	@SuppressWarnings("checkstyle:MultipleStringLiterals")
	private static final Pattern PATTERN_ILLEGAL_XML_CHARACTERS_AT_START = Pattern.compile("^[^" + XML_NAME_START_CHARACTERS + "]+");
	/**
	 * Pattern matching any number.
	 */
	private static final Pattern PATTERN_IS_NUMBER = Pattern.compile("^(0|[1-9]\\d*)$");

	/**
	 * Returns an XML compatible tag name based on the original JSON key.
	 *
	 * 

* The node names inside a JSON DOM are compatible with the XML standard. * Therefore, keys that are invalid XML tag names are replaced inside JSON DOM. * The attribute {@code name} still contains the original JSON object key. * * @param parentNode parent node * @param jsonKey the elements JSON key * @return the XML compatible tag name */ private static String createTagName(final JsonDomNode parentNode, final String jsonKey) { // Array Element if (parentNode instanceof JsonDomElement && ((JsonDomElement) parentNode).getJsonDomValue().getType() == JsonDomType.ARRAY) { return "element"; } // Empty if (jsonKey.isEmpty()) { return "empty"; } // Spaces final String trimmedName = jsonKey.trim(); if (trimmedName.isEmpty()) { return jsonKey.length() == 1 ? "whitespace" : "whitespaces"; } // Numeric if (Patterns.matches(PATTERN_IS_NUMBER, trimmedName).isPresent()) { return 'n' + trimmedName; } // Simplified final String simplifiedName = Strings.replaceFirst(trimmedName, PATTERN_ILLEGAL_XML_CHARACTERS_AT_START, ""); if (!simplifiedName.isEmpty()) { return Strings.replaceAll(simplifiedName, PATTERN_ILLEGAL_XML_CHARACTERS, "-"); } // Non-Empty return "non-empty"; } /** * Map of attribute names to attribute node * * @return map of attribute names to attribute node */ private final Supplier>> attributes = Finals.lazy(() -> new JsonDomNamedNodeMap<>(asList(new JsonDomAttribute<>(this, ATTRIBUTE_NAME, this::getJsonKey), new JsonDomAttribute<>(this, ATTRIBUTE_TYPE, () -> getJsonDomValue().getType().getValue())))); /** * List of child element nodes */ private final Supplier>> childNodes = Finals.lazy(() -> new JsonDomNodeList<>(getJsonDomValue().getType().isComplex() ? getJsonDomValue().getChildren().entrySet().stream().map(entry -> new JsonDomElement<>(this, entry.getKey(), entry.getValue())).collect(toList()) : singletonList(new JsonDomText<>(this, getJsonDomValue().getTextValue())))); /** * Wrapped JSON element */ private final JsonDomValue jsonDomValue; /** * The elements JSON key */ private final String jsonKey; /** * Constructor of {@link JsonDomElement}. * * @param parentNode parent node * @param jsonKey the elements JSON key * @param jsonDomValue wrapped JSON element */ public JsonDomElement(final JsonDomNode parentNode, final String jsonKey, final JsonDomValue jsonDomValue) { super(parentNode, createTagName(parentNode, jsonKey)); this.jsonDomValue = jsonDomValue; this.jsonKey = jsonKey; } /** * {@inheritDoc} */ @NonNull @Override public String getAttribute(@Nullable final String name) { final JsonDomAttribute attribute = getAttributeNode(name); return attribute == null ? "" : attribute.getValue(); } /** * {@inheritDoc} */ @Nullable @Override public JsonDomAttribute getAttributeNode(@Nullable final String name) { return Nullables.orElseThrow(getAttributes()).get(name); } /** * {@inheritDoc} */ @Nullable @Override public JsonDomAttribute getAttributeNodeNS(@Nullable @SuppressWarnings("unused") final String namespaceURI, @Nullable @SuppressWarnings("unused") final String localName) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public String getAttributeNS(@Nullable @SuppressWarnings("unused") final String namespaceURI, @Nullable @SuppressWarnings("unused") final String localName) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @NonNull @Override public JsonDomNamedNodeMap> getAttributes() { return attributes.get(); } /** * {@inheritDoc} */ @NonNull @Override public JsonDomNodeList> getChildNodes() { return childNodes.get(); } /** * {@inheritDoc} */ @NonNull @Override public JsonDomNodeList> getElementsByTagName(@Nullable final String name) { if (name == null) { return new JsonDomNodeList<>(emptyList()); } final List> list = new ArrayList<>(); for (final JsonDomNode child : getChildNodes()) { if (child instanceof JsonDomElement) { final JsonDomElement childElement = (JsonDomElement) child; if (name.equals(childElement.getTagName()) || GET_ELEMENTS_BY_TAG_NAME_WILDCARD.equals(name)) { list.add(childElement); } list.addAll(childElement.getElementsByTagName(name)); } } return new JsonDomNodeList<>(list); } /** * {@inheritDoc} */ @NonNull @Override public JsonDomNodeList> getElementsByTagNameNS(@Nullable @SuppressWarnings("unused") final String namespaceURI, @Nullable @SuppressWarnings("unused") final String localName) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public T getJsonElement() { return getJsonDomValue().getJsonElement(); } /** * {@inheritDoc} */ @Nullable @Override @SuppressWarnings("PMD.CompareObjectsWithEquals") public final JsonDomNode getNextSibling() { final JsonDomNode parentNode = Nullables.orElseThrow(getParentNode()); final JsonDomNodeList> childNodes = Nullables.orElseThrow(parentNode.getChildNodes()); final Iterator> iterator = childNodes.iterator(); while (iterator.hasNext()) { if (iterator.next() == this) { return iterator.hasNext() ? iterator.next() : null; } } return null; } /** * {@inheritDoc} */ @Override public short getNodeType() { return Node.ELEMENT_NODE; } /** * {@inheritDoc} */ @Nullable @Override public String getNodeValue() { return null; } /** * {@inheritDoc} */ @NonNull @Override public JsonDomDocument getOwnerDocument() { return Nullables.orElseThrow(getParentNode()).getOwnerDocument(); } /** * {@inheritDoc} */ @Nullable @Override @SuppressWarnings("PMD.CompareObjectsWithEquals") public final JsonDomNode getPreviousSibling() { JsonDomNode previousSibling = null; JsonDomNode currentSibling = null; final JsonDomNode parentNode = Nullables.orElseThrow(getParentNode()); final JsonDomNodeList> childNodes = Nullables.orElseThrow(parentNode.getChildNodes()); final Iterator> iterator = childNodes.iterator(); while (currentSibling != this) { previousSibling = currentSibling; currentSibling = iterator.next(); } return previousSibling; } /** * {@inheritDoc} */ @Nullable @Override public TypeInfo getSchemaTypeInfo() { return null; } /** * {@inheritDoc} */ @NonNull @Override public String getTagName() { return getNodeName(); } /** * {@inheritDoc} */ @NonNull @Override public String getTextContent() { return ""; } /** * {@inheritDoc} */ @Override public boolean hasAttribute(@Nullable final String name) { return Nullables.orElseThrow(getAttributes()).containsKey(name); } /** * {@inheritDoc} */ @Override public boolean hasAttributeNS(@Nullable @SuppressWarnings("unused") final String namespaceURI, @Nullable @SuppressWarnings("unused") final String localName) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public void removeAttribute(@Nullable @SuppressWarnings("unused") final String name) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @NonNull @Override public JsonDomAttribute removeAttributeNode(@Nullable @SuppressWarnings("unused") final Attr oldAttr) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public void removeAttributeNS(@Nullable @SuppressWarnings("unused") final String namespaceURI, @Nullable @SuppressWarnings("unused") final String localName) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public void setAttribute(@Nullable @SuppressWarnings("unused") final String name, @Nullable @SuppressWarnings("unused") final String value) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @NonNull @Override public JsonDomAttribute setAttributeNode(@Nullable @SuppressWarnings("unused") final Attr newAttr) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Nullable @Override public JsonDomAttribute setAttributeNodeNS(@Nullable @SuppressWarnings("unused") final Attr newAttr) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public void setAttributeNS(@Nullable @SuppressWarnings("unused") final String namespaceURI, @Nullable @SuppressWarnings("unused") final String qualifiedName, @Nullable @SuppressWarnings("unused") final String value) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public void setIdAttribute(@Nullable @SuppressWarnings("unused") final String name, @SuppressWarnings("unused") final boolean isId) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public void setIdAttributeNode(@Nullable @SuppressWarnings("unused") final Attr idAttr, @SuppressWarnings("unused") final boolean isId) { throw new JsonDomNotSupportedException(); } /** * {@inheritDoc} */ @Override public void setIdAttributeNS(@Nullable @SuppressWarnings("unused") final String namespaceURI, @Nullable @SuppressWarnings("unused") final String localName, @SuppressWarnings("unused") final boolean isId) { throw new JsonDomNotSupportedException(); } /** * Wrapped JSON element * * @return wrapped JSON element */ @java.lang.SuppressWarnings("all") @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(justification = "generated code") @lombok.Generated public JsonDomValue getJsonDomValue() { return this.jsonDomValue; } /** * The elements JSON key * * @return the elements JSON key */ @java.lang.SuppressWarnings("all") @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(justification = "generated code") @lombok.Generated public String getJsonKey() { return this.jsonKey; } @java.lang.Override @java.lang.SuppressWarnings("all") @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(justification = "generated code") @lombok.Generated public boolean equals(@edu.umd.cs.findbugs.annotations.Nullable final java.lang.Object o) { if (o == this) return true; if (!(o instanceof JsonDomElement)) return false; final JsonDomElement other = (JsonDomElement) o; if (!other.canEqual((java.lang.Object) this)) return false; if (!super.equals(o)) return false; final java.lang.Object this$attributes = this.getAttributes(); final java.lang.Object other$attributes = other.getAttributes(); if (this$attributes == null ? other$attributes != null : !this$attributes.equals(other$attributes)) return false; final java.lang.Object this$childNodes = this.getChildNodes(); final java.lang.Object other$childNodes = other.getChildNodes(); if (this$childNodes == null ? other$childNodes != null : !this$childNodes.equals(other$childNodes)) return false; final java.lang.Object this$jsonDomValue = this.getJsonDomValue(); final java.lang.Object other$jsonDomValue = other.getJsonDomValue(); if (this$jsonDomValue == null ? other$jsonDomValue != null : !this$jsonDomValue.equals(other$jsonDomValue)) return false; final java.lang.Object this$jsonKey = this.getJsonKey(); final java.lang.Object other$jsonKey = other.getJsonKey(); if (this$jsonKey == null ? other$jsonKey != null : !this$jsonKey.equals(other$jsonKey)) return false; return true; } @java.lang.SuppressWarnings("all") @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(justification = "generated code") @lombok.Generated protected boolean canEqual(@edu.umd.cs.findbugs.annotations.Nullable final java.lang.Object other) { return other instanceof JsonDomElement; } @java.lang.Override @java.lang.SuppressWarnings("all") @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(justification = "generated code") @lombok.Generated public int hashCode() { final int PRIME = 59; int result = super.hashCode(); final java.lang.Object $attributes = this.getAttributes(); result = result * PRIME + ($attributes == null ? 43 : $attributes.hashCode()); final java.lang.Object $childNodes = this.getChildNodes(); result = result * PRIME + ($childNodes == null ? 43 : $childNodes.hashCode()); final java.lang.Object $jsonDomValue = this.getJsonDomValue(); result = result * PRIME + ($jsonDomValue == null ? 43 : $jsonDomValue.hashCode()); final java.lang.Object $jsonKey = this.getJsonKey(); result = result * PRIME + ($jsonKey == null ? 43 : $jsonKey.hashCode()); return result; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy