wffweb/src/main/java/com/webfirmframework/wffweb/tag/repository/TagRepository.java
public AbstractHtml findOneTagByAttributeName(final boolean parallel,
            final String attributeName) throws NullValueException {

        if (attributeName == null) {
            throw new NullValueException(
                    "The attributeName should not be null");
        }
        final Collection<Lock> locks = getReadLocks(rootTags);
        for (final Lock lock : locks) {
            lock.lock();
        }

        try {
            final Stream<AbstractHtml> stream = buildAllTagsStream(parallel);

            final Optional<AbstractHtml> any = stream.filter(tag -> {
                return tag.getAttributeByName(attributeName) != null;
            }).findAny();

            if (any.isPresent()) {
                return any.get();
            }

            return null;
        } finally {
            for (final Lock lock : locks) {
                lock.unlock();
            }
        }
    }
public AbstractHtml findOneTagByAttributeName(final boolean parallel,
            final String attributeName) throws NullValueException {

        if (attributeName == null) {
            throw new NullValueException(
                    "The attributeName should not be null");
        }
        final Collection<Lock> locks = getReadLocks(rootTags);
        for (final Lock lock : locks) {
            lock.lock();
        }

        try {
            final Stream<AbstractHtml> stream = buildAllTagsStream(parallel);

            final Optional<AbstractHtml> any = stream.filter(tag -> {
                return tag.getAttributeByName(attributeName) != null;
            }).findAny();

            if (any.isPresent()) {
                return any.get();
            }

            return null;
        } finally {
            for (final Lock lock : locks) {
                lock.unlock();
            }
        }
    }
Finds and returns the first (including the nested tags) matching with the
given attribute name.

@param parallel
true to internally use parallel stream. If true
it will split the finding task to different
batches and will execute the batches in
different threads in parallel consuming all
CPUs. It will perform faster in finding from
extremely large number of tags but at the same
time it will less efficient in finding from
small number of tags.
@param attributeName
the name of the attribute.
@return the first matching tag with the given attribute name and value.
@throws NullValueException
if the {@code attributeName} is null
@since 3.0.0
@author WFF