// Copyright 2006, 2007 The Apache Software Foundation // // 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.anjlab.eclipse.tapestry5.internal; import java.util.ArrayList; import java.util.List; /** * Used by {@link org.apache.tapestry5.ioc.internal.util.Orderer} to establish backward dependencies for {@link * org.apache.tapestry5.ioc.Orderable} objects. * * @param <T> */ class DependencyNode<T> { private final Orderable<T> orderable; private final List<DependencyNode<T>> dependencies = new ArrayList<DependencyNode<T>>(); DependencyNode(Orderable<T> orderable) { this.orderable = orderable; } @Override public String toString() { StringBuilder buffer = new StringBuilder(String.format("[%s", getId())); boolean first = true; for (DependencyNode<T> node : dependencies) { buffer.append(first ? ": " : ", "); buffer.append(node.toString()); first = false; } buffer.append("]"); return buffer.toString(); } /** * Returns the underlying {@link Orderable}'s id. */ public String getId() { return orderable.getId(); } void addDependency(DependencyNode<T> node) { if (node.isReachable(this)) { return; } // Make this node depend on the other node. // That forces the other node's orderable // to appear before this node's orderable. dependencies.add(node); } boolean isReachable(DependencyNode<T> node) { if (this == node) return true; // Quick fast pass for immediate dependencies for (DependencyNode<T> d : dependencies) { if (d == node) return true; } // Slower second pass looks for // indirect dependencies for (DependencyNode<T> d : dependencies) { if (d.isReachable(node)) return true; } return false; } /** * Returns the {@link Orderable} objects for this node ordered based on dependencies. */ List<Orderable<T>> getOrdered() { List<Orderable<T>> result = new ArrayList<Orderable<T>>(); fillOrder(result); return result; } private void fillOrder(List<Orderable<T>> list) { if (list.contains(orderable)) return; // Recusively add dependencies for (DependencyNode<T> node : dependencies) { node.fillOrder(list); } list.add(orderable); } }