1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.geronimo.st.core.internal; 19 20 import java.util.Collections; 21 import java.util.HashMap; 22 import java.util.LinkedHashSet; 23 import java.util.Iterator; 24 import java.util.Map; 25 import java.util.Set; 26 27 import org.apache.geronimo.jee.deployment.Artifact; 28 29 /** 30 * <b>DependencyManager</b> is very closely-based on the similar class in the Geronimo server. 31 * DependencyManager is the record keeper of the dependencies in the Geronimo Eclipse Plugin. The 32 * DependencyManager does not enforce any dependencies, it is simply a place where components can 33 * register their intent to be dependent on another component, and where other components can query 34 * those dependencies. 35 * 36 * <p>Like the DependencyManager in the Geronimo server, it uses the nomenclature of parent-child 37 * where a child is dependent on a parent. The names parent and child have no other meaning are just 38 * a convenience to make the code readable. 39 * 40 * <p>The initial usage of this DependencyManager in the GEP is somewhat limited but other usages 41 * are possible<p> 42 * 43 * @version $Rev: 680897 $ $Date: 2008-07-30 09:18:42 +0800 (Wed, 30 Jul 2008) $ 44 */ 45 public class DependencyManager { 46 47 // 48 // Map from child to a list of parents 49 // 50 private final Map childToParentMap = new HashMap(); 51 52 // 53 // Map from parent back to a list of its children 54 // 55 private final Map parentToChildMap = new HashMap(); 56 57 58 /** 59 * 60 */ 61 public void close() { 62 childToParentMap.clear(); 63 parentToChildMap.clear(); 64 } 65 66 67 /** 68 * Declares a dependency from a child to a parent. 69 * 70 * @param child the dependent component 71 * @param parent the component the child is depending on 72 */ 73 public void addDependency(Artifact child, Artifact parent) { 74 Trace.tracePoint("Entry", "DependencyManager.addDependency", child, parent); 75 76 Set parents = (Set) childToParentMap.get(child); 77 if (parents == null) { 78 parents = new LinkedHashSet(); 79 childToParentMap.put(child, parents); 80 } 81 parents.add(parent); 82 83 Set children = (Set) parentToChildMap.get(parent); 84 if (children == null) { 85 children = new LinkedHashSet(); 86 parentToChildMap.put(parent, children); 87 } 88 children.add(child); 89 90 Trace.tracePoint("Exit ", "DependencyManager.addDependency", childToParentMap.size() ); 91 Trace.tracePoint("Exit ", "DependencyManager.addDependency", parentToChildMap.size() ); 92 } 93 94 95 /** 96 * Removes a dependency from a child to a parent 97 * 98 * @param child the dependnet component 99 * @param parent the component that the child wil no longer depend on 100 */ 101 public void removeDependency(Artifact child, Artifact parent) { 102 Trace.tracePoint("Entry", "DependencyManager.removeDependency", child, parent); 103 104 Set parents = (Set) childToParentMap.get(child); 105 if (parents != null) { 106 parents.remove(parent); 107 } 108 109 Set children = (Set) parentToChildMap.get(parent); 110 if (children != null) { 111 children.remove(child); 112 } 113 114 Trace.tracePoint("Exit ", "DependencyManager.addDependency"); 115 } 116 117 118 /** 119 * Removes all dependencies for a child 120 * 121 * @param child the component that will no longer depend on anything 122 */ 123 public void removeAllDependencies(Artifact child) { 124 Trace.tracePoint("Entry", "DependencyManager.removeAllDependencies", child); 125 126 Set parents = (Set) childToParentMap.remove(child); 127 if (parents == null) { 128 return; 129 } 130 131 for (Iterator iterator = parents.iterator(); iterator.hasNext();) { 132 Artifact parent = (Artifact) iterator.next(); 133 Set children = (Set) parentToChildMap.get(parent); 134 if (children != null) { 135 children.remove(child); 136 } 137 } 138 139 Trace.tracePoint("Exit ", "DependencyManager.removeAllDependencies"); 140 } 141 142 143 /** 144 * Adds dependencies from the child to every parent in the parents set 145 * 146 * @param child the dependent component 147 * @param parents the set of components the child is depending on 148 */ 149 public void addDependencies(Artifact child, Set parents) { 150 Trace.tracePoint("Entry", "DependencyManager.addDependencies", child, parents); 151 152 Set existingParents = (Set) childToParentMap.get(child); 153 if (existingParents == null) { 154 existingParents = new LinkedHashSet(parents); 155 childToParentMap.put(child, existingParents); 156 } 157 else { 158 existingParents.addAll(parents); 159 } 160 161 for (Iterator i = parents.iterator(); i.hasNext();) { 162 Object startParent = i.next(); 163 Set children = (Set) parentToChildMap.get(startParent); 164 if (children == null) { 165 children = new LinkedHashSet(); 166 parentToChildMap.put(startParent, children); 167 } 168 children.add(child); 169 } 170 171 Trace.tracePoint("Exit ", "DependencyManager.addDependencies"); 172 } 173 174 175 /** 176 * Gets the set of parents that the child is depending on 177 * 178 * @param child the dependent component 179 * @return a collection containing all of the components the child depends on; will never be null 180 */ 181 public Set getParents(Artifact child) { 182 Trace.tracePoint("Entry", "DependencyManager.getParents", child); 183 184 Set parents = (Set) childToParentMap.get(child); 185 if (parents == null) { 186 Trace.tracePoint("Exit", "DependencyManager.getParents", 0); 187 return Collections.EMPTY_SET; 188 } 189 190 Trace.tracePoint("Exit", "DependencyManager.getParents", parents.size() ); 191 return new LinkedHashSet(parents); 192 } 193 194 195 /** 196 * Gets all of the children that have a dependency on the specified parent. 197 * 198 * @param parent the component the returned childen set depend on 199 * @return a collection containing all of the components that depend on the parent; will never be null 200 */ 201 public Set getChildren(Artifact parent) { 202 Trace.tracePoint("Entry", "DependencyManager.getChildren", parent); 203 204 Set children = (Set) parentToChildMap.get(parent); 205 if (children == null) { 206 Trace.tracePoint("Exit ", "DependencyManager.getChildren", 0); 207 return Collections.EMPTY_SET; 208 } 209 210 Trace.tracePoint("Exit ", "DependencyManager.getChildren", children.size() ); 211 return new LinkedHashSet(children); 212 } 213 }