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

nz.net.ultraq.thymeleaf.internal.MetaClass Maven / Gradle / Ivy

package nz.net.ultraq.thymeleaf.internal;

import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
import org.thymeleaf.dom.AbstractTextNode;
import org.thymeleaf.dom.Attribute;
import org.thymeleaf.dom.Document;
import org.thymeleaf.dom.Element;
import org.thymeleaf.dom.NestableNode;
import org.thymeleaf.dom.Node;
import org.thymeleaf.dom.Text;

/**
 *
 * @author zhanhb
 */
public class MetaClass {

    /**
     * get the last index which the element matches the predicate.
     *
     * @param 
     * @param list
     * @param predicate
     * @return
     */
    public static  int lastIndexOf(List list, Predicate predicate) {
        ListIterator it = list.listIterator(list.size());

        while (it.hasPrevious()) {
            if (predicate.test(it.previous())) {
                return it.nextIndex();
            }
        }
        return -1;
    }

    /**
     * Searches this and all children of this element for an element of the
     * given name.
     *
     * @param delegate
     * @param name
     * @return The matching element, or null if no match was found.
     */
    public static Element findElement(Element delegate, String name) {
        Function[] search = new Function[1];
        search[0] = element -> {
            if (Objects.equals(element.getOriginalName(), name)) {
                return element;
            }
            return element.getElementChildren().stream().map(search[0]).filter(Objects::nonNull)
                    .findFirst().orElse(null);
        };
        return search[0].apply(delegate);
    }

    /**
     * Returns an attribute processor's value, checks both prefix:processor and
     * data-prefix-processor variants.
     *
     * @param delegate
     * @param prefix
     * @param name
     * @return The value of the matching processor, or null if the
     * processor doesn't exist on the element.
     */
    public static String getAttributeValue(Element delegate, String prefix, String name) {
        String attributeValue = delegate.getAttributeValue(prefix + ":" + name);
        if (attributeValue == null || attributeValue.isEmpty()) {
            attributeValue = delegate.getAttributeValue("data-" + prefix + "-" + name);
        }
        return attributeValue;
    }

    /**
     * Removes an attribute processor from this element, checks both
     * prefix:processor and data-prefix-processor variants.
     *
     * @param delegate
     * @param prefix
     * @param name
     */
    public static void removeAttribute(Element delegate, String prefix, String name) {
        delegate.removeAttribute(prefix + ":" + name);
        delegate.removeAttribute("data-" + prefix + "-" + name);
    }

    /**
     * Inserts a child node, creating a whitespace node before it so that it
     * appears in line with all the existing children.
     *
     * @param delegate
     * @param child Node to add.
     * @param index Node position.
     */
    public static void insertChildWithWhitespace(Element delegate, Node child, int index) {
        if (child != null) {
            NestableNode parent = delegate.getParent();
            Text whitespace;
            if (parent instanceof Document) {
                whitespace = new Text("\n\t");
            } else {
                List parentChildren = parent.getChildren();
                Node get = parentChildren.get(parentChildren.indexOf(delegate) - 1);
                whitespace = new Text(((AbstractTextNode) get).getContent() + '\t');
            }
            delegate.insertChild(index, whitespace);
            delegate.insertChild(index + 1, child);
        }
    }

    /**
     * Removes a child node and the whitespace node immediately before so that
     * the area doesn't appear too messy.
     *
     * @param delegate
     * @param child Node to remove
     */
    public static void removeChildWithWhitespace(Element delegate, Node child) {
        if (child != null) {
            List children = delegate.getChildren();
            int index = children.indexOf(child);
            delegate.removeChild(index);
            if (index > 0) {
                delegate.removeChild(index - 1);
            }
        }
    }

    /**
     * Returns whether or not this node represents collapsible whitespace.
     *
     * @param delegate
     * @return true if this is a collapsible text node.
     */
    public static boolean isWhitespaceNode(Node delegate) {
        return delegate instanceof Text && ((Text) delegate).getContent().trim().isEmpty();
    }

    /**
     * Returns whether or not an attribute is an attribute processor of the
     * given name, checks both prefix:processor and data-prefix-processor
     * variants.
     *
     * @param delegate
     * @param prefix
     * @param name
     * @return true if this attribute is an attribute processor of the
     * matching name.
     */
    public static boolean equalsName(Attribute delegate, String prefix, String name) {
        String originalName = delegate.getOriginalName();
        return Objects.equals(originalName, prefix + ":" + name) || Objects.equals(originalName, "data-" + prefix + "-" + name);
    }

    /**
     * Returns whether or not the element has an attribute processor, checks
     * both prefix:processor and data-prefix-processor variants.
     *
     * @param delegate
     * @param prefix
     * @param name
     * @return true if the processor exists on the element.
     */
    public static boolean hasAttribute(Element delegate, String prefix, String name) {
        return delegate.hasAttribute(prefix + ":" + name)
                || delegate.hasAttribute("data-" + prefix + "-" + name);
    }

    private MetaClass() {
        throw new AssertionError();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy