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 }