1 package org.eclipse.aether.util.graph.visitor; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import java.util.IdentityHashMap; 23 import java.util.Map; 24 25 import org.eclipse.aether.graph.DefaultDependencyNode; 26 import org.eclipse.aether.graph.DependencyNode; 27 import org.eclipse.aether.graph.DependencyVisitor; 28 29 /** 30 * A dependency visitor that constructs a clone of the visited dependency graph. If such a visitor is passed into a 31 * {@link FilteringDependencyVisitor}, a sub graph can be created. This class creates shallow clones of the visited 32 * dependency nodes (via {@link DefaultDependencyNode#DefaultDependencyNode(DependencyNode)}) but clients can create a 33 * subclass and override {@link #clone(DependencyNode)} to alter the clone process. 34 */ 35 public class CloningDependencyVisitor 36 implements DependencyVisitor 37 { 38 39 private final Map<DependencyNode, DependencyNode> clones; 40 41 private final Stack<DependencyNode> parents; 42 43 private DependencyNode root; 44 45 /** 46 * Creates a new visitor that clones the visited nodes. 47 */ 48 public CloningDependencyVisitor() 49 { 50 parents = new Stack<>(); 51 clones = new IdentityHashMap<>( 256 ); 52 } 53 54 /** 55 * Gets the root node of the cloned dependency graph. 56 * 57 * @return The root node of the cloned dependency graph or {@code null}. 58 */ 59 public final DependencyNode getRootNode() 60 { 61 return root; 62 } 63 64 /** 65 * Creates a clone of the specified node. 66 * 67 * @param node The node to clone, must not be {@code null}. 68 * @return The cloned node, never {@code null}. 69 */ 70 protected DependencyNode clone( DependencyNode node ) 71 { 72 return new DefaultDependencyNode( node ); 73 } 74 75 public final boolean visitEnter( DependencyNode node ) 76 { 77 boolean recurse = true; 78 79 DependencyNode clone = clones.get( node ); 80 if ( clone == null ) 81 { 82 clone = clone( node ); 83 clones.put( node, clone ); 84 } 85 else 86 { 87 recurse = false; 88 } 89 90 DependencyNode parent = parents.peek(); 91 92 if ( parent == null ) 93 { 94 root = clone; 95 } 96 else 97 { 98 parent.getChildren().add( clone ); 99 } 100 101 parents.push( clone ); 102 103 return recurse; 104 } 105 106 public final boolean visitLeave( DependencyNode node ) 107 { 108 parents.pop(); 109 110 return true; 111 } 112 113 }