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

org.camunda.bpm.engine.impl.tree.ReferenceWalker Maven / Gradle / Ivy

There is a newer version: 7.22.0-alpha5
Show newest version
/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. Camunda licenses this file to you under the Apache License,
 * Version 2.0; 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 org.camunda.bpm.engine.impl.tree;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
 * 

A walker for walking through an object reference structure (e.g. an execution tree). * Any visited element can have any number of following elements. The elements are visited * with a breadth-first approach: The walker maintains a list of next elements to which it adds * a new elements at the end whenever it has visited an element. The walker stops when it encounters * an element that fulfills the given {@link WalkCondition}. * *

Subclasses define the type of objects and provide the walking behavior. * * @author Thorben Lindhauer */ public abstract class ReferenceWalker { protected List currentElements; protected List> preVisitor = new ArrayList>(); protected List> postVisitor = new ArrayList>(); protected abstract Collection nextElements(); public ReferenceWalker(T initialElement) { currentElements = new LinkedList(); currentElements.add(initialElement); } public ReferenceWalker(List initialElements) { currentElements = new LinkedList(initialElements); } public ReferenceWalker addPreVisitor(TreeVisitor collector) { this.preVisitor.add(collector); return this; } public ReferenceWalker addPostVisitor(TreeVisitor collector) { this.postVisitor.add(collector); return this; } public T walkWhile() { return walkWhile(new ReferenceWalker.NullCondition()); } public T walkUntil() { return walkUntil(new ReferenceWalker.NullCondition()); } public T walkWhile(ReferenceWalker.WalkCondition condition) { while (!condition.isFulfilled(getCurrentElement())) { for (TreeVisitor collector : preVisitor) { collector.visit(getCurrentElement()); } currentElements.addAll(nextElements()); currentElements.remove(0); for (TreeVisitor collector : postVisitor) { collector.visit(getCurrentElement()); } } return getCurrentElement(); } public T walkUntil(ReferenceWalker.WalkCondition condition) { do { for (TreeVisitor collector : preVisitor) { collector.visit(getCurrentElement()); } currentElements.addAll(nextElements()); currentElements.remove(0); for (TreeVisitor collector : postVisitor) { collector.visit(getCurrentElement()); } } while (!condition.isFulfilled(getCurrentElement())); return getCurrentElement(); } public T getCurrentElement() { return currentElements.isEmpty() ? null : currentElements.get(0); } public interface WalkCondition { boolean isFulfilled(S element); } public static class NullCondition implements ReferenceWalker.WalkCondition { public boolean isFulfilled(S element) { return element == null; } public static ReferenceWalker.WalkCondition notNull() { return new NullCondition(); } } }