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 Paul Hammant * 009 *****************************************************************************/ 010 011 package org.picocontainer.gems.monitors; 012 013 import org.picocontainer.ComponentMonitor; 014 import org.picocontainer.defaults.DelegatingComponentMonitor; 015 016 import java.lang.reflect.Constructor; 017 import java.util.*; 018 019 public class DotDependencyGraphComponentMonitor extends DelegatingComponentMonitor implements ComponentMonitor { 020 021 ArrayList allInstantiated = new ArrayList(); 022 023 public DotDependencyGraphComponentMonitor(ComponentMonitor delegate) { 024 super(delegate); 025 } 026 027 public DotDependencyGraphComponentMonitor() { 028 } 029 030 public void instantiated(Constructor constructor, Object instantiated, Object[] injected, long duration) { 031 032 this.allInstantiated.add(new Instantiation(constructor, instantiated, injected, duration)); 033 034 super.instantiated(constructor, instantiated, injected, duration); 035 } 036 037 038 public String getClassDependencyGraph() { 039 040 HashSet lines = new HashSet(); 041 042 for (int i = 0; i < allInstantiated.size(); i++) { 043 Instantiation instantiation = (Instantiation) allInstantiated.get(i); 044 for (int j = 0; j < instantiation.getInjected().length; j++) { 045 Object instantiated = instantiation.getInstantiated(); 046 Object injected = instantiation.getInjected()[j]; 047 lines.add(" '" + instantiated.getClass().getName() + "' -> '" + injected.getClass().getName() + "';\n"); 048 } 049 } 050 051 return sortLines(lines); 052 } 053 054 private String sortLines(HashSet lines) { 055 ArrayList list = new ArrayList(lines); 056 Collections.sort(list); 057 058 String dependencies = ""; 059 for (Iterator iterator = list.iterator(); iterator.hasNext();) { 060 String dep = (String) iterator.next(); 061 dependencies = dependencies + dep; 062 } 063 return dependencies.replaceAll("'","\""); 064 } 065 066 public String getInterfaceDependencyGraph() { 067 HashSet lines = new HashSet(); 068 069 for (int i = 0; i < allInstantiated.size(); i++) { 070 Instantiation instantiation = (Instantiation) allInstantiated.get(i); 071 for (int j = 0; j < instantiation.getInjected().length; j++) { 072 Object injected = instantiation.getInjected()[j]; 073 Class injectedType = instantiation.getConstructor().getParameterTypes()[j]; 074 Object instantiated = instantiation.getInstantiated(); 075 if (injected.getClass() != injectedType) { 076 lines.add(" '" + instantiated.getClass().getName() + "' -> '" + injectedType.getName() + "' [style=dotted,label='needs'];\n"); 077 lines.add(" '" + injected.getClass().getName() + "' -> '" + injectedType.getName() + "' [style=dotted, color=red,label='isA'];\n"); 078 lines.add(" '" + injectedType.getName() + "' [shape=box, label=" + printClassName(injectedType) + "];\n"); 079 } else { 080 lines.add(" '" + instantiated.getClass().getName() + "' -> '" + injected.getClass().getName() + "' [label='needs'];\n"); 081 } 082 lines.add(" '" + instantiated.getClass().getName() + "' [label=" + printClassName(instantiated.getClass()) + "];\n"); 083 084 } 085 } 086 087 return sortLines(lines); 088 } 089 090 private String printClassName(Class clazz) { 091 String className = clazz.getName(); 092 return "'" + className.substring(className.lastIndexOf(".")+1) + "\\n" + clazz.getPackage().getName() + "'"; 093 094 } 095 096 private static class Instantiation { 097 Constructor constructor; 098 Object instantiated; 099 Object[] injected; 100 long duration; 101 public Instantiation(Constructor constructor, Object instantiated, Object[] injected, long duration) { 102 this.constructor = constructor; 103 this.instantiated = instantiated; 104 this.injected = injected; 105 this.duration = duration; 106 } 107 108 public Constructor getConstructor() { 109 return constructor; 110 } 111 112 public Object getInstantiated() { 113 return instantiated; 114 } 115 public Object[] getInjected() { 116 return injected; 117 } 118 } 119 }