001    package org.picocontainer.gems.monitors;
002    
003    import java.lang.reflect.Constructor;
004    
005    import org.picocontainer.defaults.DelegatingComponentMonitor;
006    import org.picocontainer.gems.monitors.prefuse.ComponentDependencyListener;
007    
008    /**
009     * Understands how to capture component dependency information from
010     * picocontainer.
011     * 
012     * @author Peter Barry
013     * @author Kent R. Spillner
014     */
015    public class ComponentDependencyMonitor extends DelegatingComponentMonitor {
016    
017        private final ComponentDependencyListener listener;
018    
019        public ComponentDependencyMonitor(ComponentDependencyListener listener) {
020            this.listener = listener;
021        }
022    
023        public void instantiated(Constructor constructor, Object instantiated, Object[] injected, long duration) {
024            Class componentType = instantiated.getClass();
025            int count = injected.length;
026    
027            if (count == 0) {
028                listener.addDependency(new Dependency(componentType, null));
029            }
030    
031            for (int i = 0; i < count; i++) {
032                Object dependent = injected[i];
033                Dependency dependency = new Dependency(componentType, dependent.getClass());
034                listener.addDependency(dependency);
035            }
036        }
037    
038        /**
039         * Understands which other classes are required to instantiate a component.
040         * 
041         * @author Peter Barry
042         * @author Kent R. Spillner
043         */
044        public static class Dependency {
045    
046            private Class componentType;
047    
048            private Class dependencyType;
049    
050            public Dependency(Class componentType, Class dependencyType) {
051                this.componentType = componentType;
052                this.dependencyType = dependencyType;
053            }
054    
055            public boolean dependsOn(Class type) {
056                return (type == null) ? false : type.equals(dependencyType);
057            }
058    
059            public boolean equals(Object other) {
060                if (other instanceof Dependency) {
061                    Dependency otherDependency = (Dependency) other;
062                    return areEqualOrNull(componentType, otherDependency.componentType)
063                            && areEqualOrNull(dependencyType, otherDependency.dependencyType);
064                }
065                return false;
066            }
067    
068            public Class getComponentType() {
069                return componentType;
070            }
071    
072            public Class getDependencyType() {
073                return dependencyType;
074            }
075    
076            public String toString() {
077                return componentType + " depends on " + dependencyType;
078            }
079    
080            private static boolean areEqualOrNull(Class type, Class otherType) {
081                if (type != null) {
082                    return type.equals(otherType);
083                }
084                return (type == null && otherType == null);
085            }
086        }
087    }