/* * Copyright (c) 2013-2016 Chris Newland. * Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD * Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki */ package org.adoptopenjdk.jitwatch.model; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_CLOSE_ANGLE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_DOUBLE_QUOTE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_EQUALS; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_NEWLINE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_OPEN_ANGLE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_SLASH; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_SPACE; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.adoptopenjdk.jitwatch.util.StringUtil; public class Tag { private String name; private String attributeString; private List<Tag> children = new ArrayList<>(); private Tag parent = null; private boolean selfClosing = false; private boolean isFragment = false; private String textContent = null; private static final String INDENT = " "; public Tag(String name, String attributeString, boolean selfClosing) { this.name = name; this.attributeString = attributeString; this.selfClosing = selfClosing; } public void addTextContent(String text) { if (textContent == null) { textContent = text; } else { textContent += text; } } public String getTextContent() { return textContent; } public void addChild(Tag child) { child.setParent(this); children.add(child); } public List<Tag> getChildren() { return Collections.unmodifiableList(children); } public boolean isSelfClosing() { return selfClosing; } public String getClosingTag() { StringBuilder builder = new StringBuilder(); builder.append(C_OPEN_ANGLE).append(C_SLASH).append(name).append(C_CLOSE_ANGLE); return builder.toString(); } public Tag getFirstNamedChild(String name) { List<Tag> namedChildren = getNamedChildren(name); if (namedChildren.size() > 0) { return namedChildren.get(0); } else { return null; } } public List<Tag> getNamedChildren(String name) { List<Tag> result = new ArrayList<>(); for (Tag child : children) { if (child.getName().equals(name)) { result.add(child); } } return result; } public List<Tag> getNamedChildrenWithAttribute(String tagName, String attrName, String attrValue) { List<Tag> result = new ArrayList<>(); for (Tag child : children) { if (child.getName().equals(tagName)) { Map<String, String> attributes = child.getAttributes(); if (attrValue != null && attrValue.equals(attributes.get(attrName))) { result.add(child); } } } return result; } public Tag getParent() { return parent; } public void setParent(Tag parent) { this.parent = parent; } public String getName() { return name; } public Map<String, String> getAttributes() { return StringUtil.attributeStringToMap(attributeString); } private int getDepth(Tag tag) { if (tag.getParent() != null) { return 1 + getDepth(tag.getParent()); } else { return 0; } } @Override public String toString() { return toString(true); } public String toString(boolean showChildren) { StringBuilder builder = new StringBuilder(); int myDepth = getDepth(this); for (int i = 0; i < myDepth; i++) { builder.append(INDENT); } builder.append(C_OPEN_ANGLE).append(name); Map<String,String> attrs = getAttributes(); if (attrs.size() > 0) { for (Map.Entry<String, String> entry : attrs.entrySet()) { builder.append(C_SPACE).append(entry.getKey()).append(C_EQUALS).append(C_DOUBLE_QUOTE); builder.append(entry.getValue()).append(C_DOUBLE_QUOTE); } } if (selfClosing) { builder.append(C_SLASH).append(C_CLOSE_ANGLE).append(C_NEWLINE); } else { if (showChildren && children.size() > 0) { builder.append(C_CLOSE_ANGLE).append(C_NEWLINE); for (Tag child : children) { builder.append(child.toString()); } } else { builder.append(C_CLOSE_ANGLE).append(C_NEWLINE); if (textContent != null) { for (int i = 0; i < myDepth; i++) { builder.append(INDENT); } builder.append(textContent).append(C_NEWLINE); } } for (int i = 0; i < myDepth; i++) { builder.append(INDENT); } builder.append(C_OPEN_ANGLE).append(C_SLASH); builder.append(name).append(C_CLOSE_ANGLE).append(C_NEWLINE); } return builder.toString(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Tag tag = (Tag) o; if (selfClosing != tag.selfClosing) { return false; } if (attributeString != null ? !attributeString.equals(tag.attributeString) : tag.attributeString != null) { return false; } if (children != null ? !children.equals(tag.children) : tag.children != null) { return false; } if (name != null ? !name.equals(tag.name) : tag.name != null) { return false; } if (parent != null ? !parent.equals(tag.parent) : tag.parent != null) { return false; } if (textContent != null ? !textContent.equals(tag.textContent) : tag.textContent != null) { return false; } return true; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (attributeString != null ? attributeString.hashCode() : 0); result = 31 * result + (parent != null ? parent.hashCode() : 0); result = 31 * result + (selfClosing ? 1 : 0); result = 31 * result + (textContent != null ? textContent.hashCode() : 0); return result; } public boolean isFragment() { return isFragment; } public void setFragment(boolean isFragment) { this.isFragment = isFragment; } }