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

com.helger.tree.util.TreeVisitor Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014-2024 Philip Helger (www.helger.com)
 * philip[at]helger[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.helger.tree.util;

import java.util.function.Function;

import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;

import org.w3c.dom.traversal.TreeWalker;

import com.helger.commons.ValueEnforcer;
import com.helger.commons.annotation.PresentForCodeCoverage;
import com.helger.commons.hierarchy.ChildrenProviderHasChildren;
import com.helger.commons.hierarchy.IChildrenProvider;
import com.helger.commons.hierarchy.visit.ChildrenProviderHierarchyVisitor;
import com.helger.commons.hierarchy.visit.DefaultHierarchyVisitorCallback;
import com.helger.commons.hierarchy.visit.EHierarchyVisitorReturn;
import com.helger.commons.hierarchy.visit.IHierarchyVisitorCallback;
import com.helger.tree.IBasicTree;
import com.helger.tree.IBasicTreeItem;

/**
 * A specialized walker that iterates all elements in a tree and calls a
 * callback method. Compared to {@link TreeWalker} the callbacks used in this
 * class allow to stop iteration or to skip all siblings.
 *
 * @author Philip Helger
 */
@Immutable
public final class TreeVisitor
{
  public static class HierarchyVisitorCallbackWithConversion  extends
                                                             DefaultHierarchyVisitorCallback 
  {
    private final IHierarchyVisitorCallback  m_aDataCallback;
    private final Function  m_aConverter;

    public HierarchyVisitorCallbackWithConversion (@Nonnull final IHierarchyVisitorCallback  aDataCallback,
                                                   @Nonnull final Function  aConverter)
    {
      m_aDataCallback = ValueEnforcer.notNull (aDataCallback, "DataCallback");
      m_aConverter = ValueEnforcer.notNull (aConverter, "Converter");
    }

    @Override
    public void begin ()
    {
      super.begin ();
      m_aDataCallback.begin ();
    }

    @Override
    public void onLevelDown ()
    {
      super.onLevelDown ();
      m_aDataCallback.onLevelDown ();
    }

    @Override
    public void onLevelUp ()
    {
      m_aDataCallback.onLevelUp ();
      super.onLevelUp ();
    }

    @Override
    @Nonnull
    public EHierarchyVisitorReturn onItemBeforeChildren (@Nonnull final ITEMTYPE aItem)
    {
      final DATATYPE aConvertedValue = m_aConverter.apply (aItem);
      return m_aDataCallback.onItemBeforeChildren (aConvertedValue);
    }

    @Override
    @Nonnull
    public EHierarchyVisitorReturn onItemAfterChildren (@Nonnull final ITEMTYPE aItem)
    {
      final DATATYPE aConvertedValue = m_aConverter.apply (aItem);
      return m_aDataCallback.onItemAfterChildren (aConvertedValue);
    }

    @Override
    public void end ()
    {
      m_aDataCallback.end ();
      super.end ();
    }
  }

  @PresentForCodeCoverage
  private static final TreeVisitor INSTANCE = new TreeVisitor ();

  private TreeVisitor ()
  {}

  public static > void visitTree (@Nonnull final IBasicTree  aTree,
                                                                                                 @Nonnull final IHierarchyVisitorCallback  aCallback)
  {
    visitTree (aTree, new ChildrenProviderHasChildren <> (), aCallback);
  }

  public static > void visitTree (@Nonnull final IBasicTree  aTree,
                                                                                                 @Nonnull final IChildrenProvider  aChildrenResolver,
                                                                                                 @Nonnull final IHierarchyVisitorCallback  aCallback)
  {
    ValueEnforcer.notNull (aTree, "Tree");
    visitTreeItem (aTree.getRootItem (), aChildrenResolver, aCallback);
  }

  public static > void visitTreeData (@Nonnull final IBasicTree  aTree,
                                                                                                     @Nonnull final IHierarchyVisitorCallback  aDataCallback)
  {
    visitTreeData (aTree, new ChildrenProviderHasChildren <> (), aDataCallback);
  }

  public static > void visitTreeData (@Nonnull final IBasicTree  aTree,
                                                                                                     @Nonnull final IChildrenProvider  aChildrenProvider,
                                                                                                     @Nonnull final IHierarchyVisitorCallback  aDataCallback)
  {
    ValueEnforcer.notNull (aTree, "Tree");

    visitTreeItemData (aTree.getRootItem (), aChildrenProvider, aDataCallback);
  }

  public static > void visitTreeItem (@Nonnull final ITEMTYPE aTreeItem,
                                                                                                     @Nonnull final IHierarchyVisitorCallback  aCallback)
  {
    ValueEnforcer.notNull (aTreeItem, "TreeItem");
    ChildrenProviderHierarchyVisitor.visitFrom (aTreeItem, aCallback, false);
  }

  public static > void visitTreeItem (@Nonnull final ITEMTYPE aTreeItem,
                                                                                                     @Nonnull final IChildrenProvider  aChildrenProvider,
                                                                                                     @Nonnull final IHierarchyVisitorCallback  aCallback)
  {
    ValueEnforcer.notNull (aTreeItem, "TreeItem");
    ChildrenProviderHierarchyVisitor.visitFrom (aTreeItem, aChildrenProvider, aCallback, false);
  }

  public static > void visitTreeItemData (@Nonnull final ITEMTYPE aTreeItem,
                                                                                                         @Nonnull final IHierarchyVisitorCallback  aDataCallback)
  {
    visitTreeItemData (aTreeItem, new ChildrenProviderHasChildren <> (), aDataCallback);
  }

  public static > void visitTreeItemData (@Nonnull final ITEMTYPE aTreeItem,
                                                                                                         @Nonnull final IChildrenProvider  aChildrenProvider,
                                                                                                         @Nonnull final IHierarchyVisitorCallback  aDataCallback)
  {
    ValueEnforcer.notNull (aDataCallback, "DataCallback");

    // Wrap callback
    visitTreeItem (aTreeItem,
                   aChildrenProvider,
                   new HierarchyVisitorCallbackWithConversion <> (aDataCallback, ITEMTYPE::getData));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy