001 /*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 * *
008 * Original code by *
009 *****************************************************************************/
010 package org.picocontainer.gems.monitors;
011
012 import java.lang.reflect.Constructor;
013
014 import org.picocontainer.monitors.AbstractComponentMonitor;
015 import org.picocontainer.gems.monitors.prefuse.ComponentDependencyListener;
016 import org.picocontainer.ComponentAdapter;
017 import org.picocontainer.PicoContainer;
018
019 /**
020 * Understands how to capture component dependency information from
021 * picocontainer.
022 *
023 * @author Peter Barry
024 * @author Kent R. Spillner
025 */
026 @SuppressWarnings("serial")
027 public final class ComponentDependencyMonitor extends AbstractComponentMonitor {
028
029
030
031 private final ComponentDependencyListener listener;
032
033 public ComponentDependencyMonitor(final ComponentDependencyListener listener) {
034 this.listener = listener;
035 }
036
037 @Override
038 public <T> void instantiated(final PicoContainer container, final ComponentAdapter<T> componentAdapter,
039 final Constructor<T> constructor,
040 final Object instantiated,
041 final Object[] injected,
042 final long duration) {
043 Class<?> componentType = instantiated.getClass();
044 int count = injected.length;
045
046 if (count == 0) {
047 listener.addDependency(new Dependency(componentType, null));
048 }
049
050 for (int i = 0; i < count; i++) {
051 Object dependent = injected[i];
052 Dependency dependency = new Dependency(componentType, dependent.getClass());
053 listener.addDependency(dependency);
054 }
055 }
056
057 /**
058 * Understands which other classes are required to instantiate a component.
059 *
060 * @author Peter Barry
061 * @author Kent R. Spillner
062 */
063 public static final class Dependency {
064
065 private final Class<?> componentType;
066
067 private final Class<?> dependencyType;
068
069 public Dependency(final Class<?> componentType, final Class<?> dependencyType) {
070 this.componentType = componentType;
071 this.dependencyType = dependencyType;
072 }
073
074 public boolean dependsOn(final Class<?> type) {
075 return (type != null) && type.equals(dependencyType);
076 }
077
078 @Override
079 public boolean equals(final Object other) {
080 if (other instanceof Dependency) {
081 Dependency otherDependency = (Dependency) other;
082 return areEqualOrNull(componentType, otherDependency.componentType)
083 && areEqualOrNull(dependencyType, otherDependency.dependencyType);
084 }
085 return false;
086 }
087
088 public Class<?> getComponentType() {
089 return componentType;
090 }
091
092 public Class<?> getDependencyType() {
093 return dependencyType;
094 }
095
096 @Override
097 public String toString() {
098 return componentType + " depends on " + dependencyType;
099 }
100
101 private static boolean areEqualOrNull(final Class<?> type, final Class<?> otherType) {
102 if (type != null) {
103 return type.equals(otherType);
104 }
105 return (otherType == null);
106 }
107 }
108 }