incubator-composer-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hamm...@apache.org
Subject svn commit: r618168 [1/2] - in /incubator/composer/trunk/composer-core: ./ src/main/java/org/apache/composer/core/monitors/ src/main/java/org/apache/composer/core/monitors/prefuse/ src/test/java/org/apache/composer/core/monitors/ src/test/java/org/apac...
Date Mon, 04 Feb 2008 04:18:00 GMT
Author: hammant
Date: Sun Feb  3 20:17:59 2008
New Revision: 618168

URL: http://svn.apache.org/viewvc?rev=618168&view=rev
Log:
add other monitors

Added:
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/CommonsLoggingComponentMonitor.java
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/ComponentDependencyMonitor.java
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitor.java
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/Log4JComponentMonitor.java
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/ComponentDependencyListener.java
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/DependencySet.java
    incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/PrefuseDependencyGraph.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentDependencyMonitorTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentMonitorHelperTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitorTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ForTestSakeAppender.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerCommonsLoggingComponentMonitorTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerLog4JComponentMonitorTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerCommonsLoggingComponentMonitorTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerLog4JComponentMonitorTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/AggregateDemoHacks.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/DependencySetTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/PrefuseDependencyGraphTestCase.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/testmodel/CompatibleTouchable.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/testmodel/DependsOnArray.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/testmodel/DependsOnDependsOnListAndVector.java
    incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/testmodel/DependsOnList.java
Modified:
    incubator/composer/trunk/composer-core/pom.xml

Modified: incubator/composer/trunk/composer-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/pom.xml?rev=618168&r1=618167&r2=618168&view=diff
==============================================================================
--- incubator/composer/trunk/composer-core/pom.xml (original)
+++ incubator/composer/trunk/composer-core/pom.xml Sun Feb  3 20:17:59 2008
@@ -13,6 +13,22 @@
       <groupId>com.thoughtworks.paranamer</groupId>
       <artifactId>paranamer</artifactId>
     </dependency>
+      <!-- For monitors -->
+      <dependency>
+          <groupId>commons-logging</groupId>
+          <artifactId>commons-logging</artifactId>
+          <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>log4j</groupId>
+          <artifactId>log4j</artifactId>
+          <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>prefuse</groupId>
+          <artifactId>prefuse</artifactId>
+          <optional>true</optional>
+      </dependency>      
   </dependencies>
 
   <build>

Added: incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/CommonsLoggingComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/CommonsLoggingComponentMonitor.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/CommonsLoggingComponentMonitor.java (added)
+++ incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/CommonsLoggingComponentMonitor.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,223 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.composer.core.monitors;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.MutableContainer;
+import org.apache.composer.core.monitors.ComponentMonitorHelper;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.*;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+
+/**
+ * A {@link ComponentMonitor} which writes to a Commons Logging {@link Log Log} instance.
+ * The Log instance can either be injected or, if not set, the {@link LogFactory LogFactory}
+ * will be used to retrieve it at every invocation of the monitor.
+ * 
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public class CommonsLoggingComponentMonitor implements ComponentMonitor, Serializable {
+
+    /**
+	 * Serialization UUID.
+	 */
+	private static final long serialVersionUID = 5863003718112457388L;
+
+	/**
+	 * Commons Logger.
+	 */
+	private Log log;
+    
+	/**
+	 * Delegate for component monitor chains.
+	 */
+    private final ComponentMonitor delegate;
+
+    /**
+     * Creates a CommonsLoggingComponentMonitor with no Log instance set.
+     * The {@link LogFactory LogFactory} will be used to retrieve the Log instance
+     * at every invocation of the monitor.
+     */
+    public CommonsLoggingComponentMonitor() {
+        delegate = new NullComponentMonitor();
+    }
+
+    /**
+     * Creates a CommonsLoggingComponentMonitor with a given Log instance class.
+     * The class name is used to retrieve the Log instance.
+     * 
+     * @param logClass the class of the Log
+     */
+    public CommonsLoggingComponentMonitor(Class<?> logClass) {
+        this(logClass.getName());
+    }
+
+    /**
+     * Creates a CommonsLoggingComponentMonitor with a given Log instance name. It uses the
+     * {@link LogFactory LogFactory} to create the Log instance.
+     * 
+     * @param logName the name of the Log
+     */
+    public CommonsLoggingComponentMonitor(String logName) {
+        this(LogFactory.getLog(logName));
+    }
+
+    /**
+     * Creates a CommonsLoggingComponentMonitor with a given Log instance
+     * 
+     * @param log the Log to write to
+     */
+    public CommonsLoggingComponentMonitor(Log log) {
+        this();
+        this.log = log;
+    }
+
+    /**
+     * Creates a CommonsLoggingComponentMonitor with a given Log instance class.
+     * The class name is used to retrieve the Log instance.
+     *
+     * @param logClass the class of the Log
+     * @param delegate the delegate
+     */
+    public CommonsLoggingComponentMonitor(Class<?> logClass, ComponentMonitor delegate) {
+        this(logClass.getName(), delegate);
+    }
+
+    /**
+     * Creates a CommonsLoggingComponentMonitor with a given Log instance name. It uses the
+     * {@link LogFactory LogFactory} to create the Log instance.
+     *
+     * @param logName the name of the Log
+     * @param delegate the delegate
+     */
+    public CommonsLoggingComponentMonitor(String logName, ComponentMonitor delegate) {
+        this(LogFactory.getLog(logName), delegate);
+    }
+
+    /**
+     * Creates a CommonsLoggingComponentMonitor with a given Log instance
+     *
+     * @param log the Log to write to
+     * @param delegate the delegate
+     */
+    public CommonsLoggingComponentMonitor(Log log, ComponentMonitor delegate) {
+        this.log = log;
+        this.delegate = delegate;
+    }
+
+
+    public <T> Constructor<T> instantiating(Container container, ComponentAdapter<T> componentAdapter,
+                                     Constructor<T> constructor
+    ) {
+        Log log = getLog(constructor);
+        if (log.isDebugEnabled()) {
+            log.debug(ComponentMonitorHelper.format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor)));
+        }
+        return delegate.instantiating(container, componentAdapter, constructor);
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] parameters,
+                             long duration) {
+        Log log = getLog(constructor);
+        if (log.isDebugEnabled()) {
+            log.debug(ComponentMonitorHelper.format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), duration, instantiated.getClass().getName(), parmsToString(parameters)));
+        }
+        delegate.instantiated(container, componentAdapter, constructor, instantiated, parameters, duration);
+    }
+
+    public <T> void instantiationFailed(Container container,
+                                    ComponentAdapter<T>  componentAdapter,
+                                    Constructor<T>  constructor,
+                                    Exception cause) {
+        Log log = getLog(constructor);
+        if (log.isWarnEnabled()) {
+            log.warn(ComponentMonitorHelper.format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), cause.getMessage()), cause);
+        }
+        delegate.instantiationFailed(container, componentAdapter, constructor, cause);
+    }
+
+    public void invoking(Container container,
+                         ComponentAdapter<?> componentAdapter,
+                         Member member,
+                         Object instance) {
+        Log log = getLog(member);
+        if (log.isDebugEnabled()) {
+            log.debug(ComponentMonitorHelper.format(ComponentMonitorHelper.INVOKING, memberToString(member), instance));
+        }
+        delegate.invoking(container, componentAdapter, member, instance);
+    }
+
+    public void invoked(Container container,
+                        ComponentAdapter<?> componentAdapter,
+                        Method method,
+                        Object instance,
+                        long duration) {
+        Log log = getLog(method);
+        if (log.isDebugEnabled()) {
+            log.debug(ComponentMonitorHelper.format(ComponentMonitorHelper.INVOKED, methodToString(method), instance, duration));
+        }
+        delegate.invoked(container, componentAdapter, method, instance,  duration);
+    }
+
+    public void invocationFailed(Member member, Object instance, Exception cause) {
+        Log log = getLog(member);
+        if (log.isWarnEnabled()) {
+            log.warn(ComponentMonitorHelper.format(ComponentMonitorHelper.INVOCATION_FAILED, memberToString(member), instance, cause.getMessage()), cause);
+        }
+        delegate.invocationFailed(member, instance, cause);
+    }
+
+    public void lifecycleInvocationFailed(MutableContainer container,
+                                          ComponentAdapter<?> componentAdapter, Method method,
+                                          Object instance,
+                                          RuntimeException cause) {
+        Log log = getLog(method);
+        if (log.isWarnEnabled()) {
+            log.warn(ComponentMonitorHelper.format(ComponentMonitorHelper.LIFECYCLE_INVOCATION_FAILED, methodToString(method), instance, cause.getMessage()), cause);
+        }
+        delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause);
+    }
+
+    public Object noComponentFound(MutableContainer container, Object componentKey) {
+        Log log = this.log != null ? this.log : LogFactory.getLog(ComponentMonitor.class);
+        if (log.isWarnEnabled()) {
+            log.warn(ComponentMonitorHelper.format(ComponentMonitorHelper.NO_COMPONENT, componentKey));
+        }
+        return delegate.noComponentFound(container, componentKey);
+    }
+
+    protected Log getLog(Member member) {
+        if ( log != null ){
+            return log;
+        } 
+        return LogFactory.getLog(member.getDeclaringClass());
+    }
+
+}

Added: incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/ComponentDependencyMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/ComponentDependencyMonitor.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/ComponentDependencyMonitor.java (added)
+++ incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/ComponentDependencyMonitor.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.monitors.prefuse.ComponentDependencyListener;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Understands how to capture component dependency information from
+ * picocontainer.
+ * 
+ * @author Peter Barry
+ * @author Kent R. Spillner
+ */
+public final class ComponentDependencyMonitor extends AbstractComponentMonitor {
+
+    /**
+	 * Serialization UUID.
+	 */
+	private static final long serialVersionUID = 9104656171384560235L;
+	
+	
+	private final ComponentDependencyListener listener;
+
+    public ComponentDependencyMonitor(ComponentDependencyListener listener) {
+        this.listener = listener;
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] injected,
+                             long duration) {
+        Class<?> componentType = instantiated.getClass();
+        int count = injected.length;
+
+        if (count == 0) {
+            listener.addDependency(new Dependency(componentType, null));
+        }
+
+        for (int i = 0; i < count; i++) {
+            Object dependent = injected[i];
+            Dependency dependency = new Dependency(componentType, dependent.getClass());
+            listener.addDependency(dependency);
+        }
+    }
+
+    /**
+     * Understands which other classes are required to instantiate a component.
+     * 
+     * @author Peter Barry
+     * @author Kent R. Spillner
+     */
+    public static final class Dependency {
+
+        private final Class<?> componentType;
+
+        private final Class<?> dependencyType;
+
+        public Dependency(Class<?> componentType, Class<?> dependencyType) {
+            this.componentType = componentType;
+            this.dependencyType = dependencyType;
+        }
+
+        public boolean dependsOn(Class<?> type) {
+            return (type != null) && type.equals(dependencyType);
+        }
+
+        public boolean equals(Object other) {
+            if (other instanceof Dependency) {
+                Dependency otherDependency = (Dependency) other;
+                return areEqualOrNull(componentType, otherDependency.componentType)
+                        && areEqualOrNull(dependencyType, otherDependency.dependencyType);
+            }
+            return false;
+        }
+
+        public Class<?> getComponentType() {
+            return componentType;
+        }
+
+        public Class<?> getDependencyType() {
+            return dependencyType;
+        }
+
+        public String toString() {
+            return componentType + " depends on " + dependencyType;
+        }
+
+        private static boolean areEqualOrNull(Class<?> type, Class<?> otherType) {
+            if (type != null) {
+                return type.equals(otherType);
+            }
+            return (otherType == null);
+        }
+    }
+}

Added: incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitor.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitor.java (added)
+++ incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitor.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,149 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.monitors.AbstractComponentMonitor;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+public final class DotDependencyGraphComponentMonitor extends AbstractComponentMonitor implements ComponentMonitor {
+
+    /**
+	 * Serialization UUID.
+	 */
+	private static final long serialVersionUID = 2220639049409365618L;
+	
+	final List<Instantiation> allInstantiated = new ArrayList<Instantiation>();
+
+    public DotDependencyGraphComponentMonitor(ComponentMonitor delegate) {
+        super(delegate);
+    }
+
+    public DotDependencyGraphComponentMonitor() {
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] injected,
+                             long duration) {
+
+        this.allInstantiated.add(new Instantiation(constructor, instantiated, injected, duration));
+
+        super.instantiated(container, componentAdapter, constructor, instantiated, injected, duration);
+    }
+
+
+    public String getClassDependencyGraph() {
+
+        Set<String> lines = new HashSet<String>();
+
+        for (Object anAllInstantiated : allInstantiated) {
+            Instantiation instantiation = (Instantiation)anAllInstantiated;
+            for (int j = 0; j < instantiation.getInjected().length; j++) {
+                Object instantiated = instantiation.getInstantiated();
+                Object injected = instantiation.getInjected()[j];
+                lines.add(
+                    "  '" + instantiated.getClass().getName() + "' -> '" + injected.getClass().getName() + "';\n");
+            }
+        }
+
+        return sortLines(lines);
+    }
+
+    private String sortLines(Set<String> lines) {
+        List<String> list = new ArrayList<String>(lines);
+        Collections.sort(list);
+
+        String dependencies = "";
+        for (Object aList : list) {
+            String dep = (String)aList;
+            dependencies = dependencies + dep;
+        }
+        return dependencies.replaceAll("'","\"");
+    }
+
+    public String getInterfaceDependencyGraph() {
+        Set<String> lines = new HashSet<String>();
+
+        for (Object anAllInstantiated : allInstantiated) {
+            Instantiation instantiation = (Instantiation)anAllInstantiated;
+            for (int j = 0; j < instantiation.getInjected().length; j++) {
+                Object injected = instantiation.getInjected()[j];
+                Class<?> injectedType = instantiation.getConstructor().getParameterTypes()[j];
+                Object instantiated = instantiation.getInstantiated();
+                if (injected.getClass() != injectedType) {
+                    lines.add("  '" + instantiated.getClass().getName() + "' -> '" + injectedType.getName() +
+                              "' [style=dotted,label='needs'];\n");
+                    lines.add("  '" + injected.getClass().getName() + "' -> '" + injectedType.getName() +
+                              "' [style=dotted, color=red,label='isA'];\n");
+                    lines.add("  '" + injectedType.getName() + "' [shape=box, label=" + printClassName(injectedType) +
+                              "];\n");
+                } else {
+                    lines.add("  '" + instantiated.getClass().getName() + "' -> '" + injected.getClass().getName() +
+                              "' [label='needs'];\n");
+                }
+                lines.add("  '" + instantiated.getClass().getName() + "' [label=" +
+                          printClassName(instantiated.getClass()) + "];\n");
+
+            }
+        }
+
+        return sortLines(lines);
+    }
+
+    private String printClassName(Class<?> clazz) {
+        String className = clazz.getName();
+        return "'" + className.substring(className.lastIndexOf(".")+1) + "\\n" + clazz.getPackage().getName() + "'";
+
+    }
+
+    private static final class Instantiation {
+        final Constructor<?> constructor;
+        final Object instantiated;
+        final Object[] injected;
+        final long duration;
+        
+        public Instantiation(Constructor<?> constructor, Object instantiated, Object[] injected, long duration) {
+            this.constructor = constructor;
+            this.instantiated = instantiated;
+            this.injected = injected;
+            this.duration = duration;
+        }
+
+        public Constructor<?> getConstructor() {
+            return constructor;
+        }
+
+        public Object getInstantiated() {
+            return instantiated;
+        }
+        public Object[] getInjected() {
+            return injected;
+        }
+    }
+}

Added: incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/Log4JComponentMonitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/Log4JComponentMonitor.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/Log4JComponentMonitor.java (added)
+++ incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/Log4JComponentMonitor.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,225 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.MutableContainer;
+import org.apache.composer.core.monitors.ComponentMonitorHelper;
+import org.apache.composer.core.monitors.NullComponentMonitor;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.*;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.Priority;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+
+/**
+ * A {@link org.picocontainer.ComponentMonitor} which writes to a Log4J {@link org.apache.log4j.Logger} instance.
+ * The Logger instance can either be injected or, if not set, the {@link LogManager LogManager}
+ * will be used to retrieve it at every invocation of the monitor.
+ *
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public class Log4JComponentMonitor implements ComponentMonitor, Serializable {
+
+	/**
+	 * Serialization UUID.
+	 */
+	private static final long serialVersionUID = 6974859796813059085L;
+
+	/**
+	 * Log4j Logger.
+	 */
+    private Logger logger;
+    
+    private final ComponentMonitor delegate;
+
+    /**
+     * Creates a Log4JComponentMonitor with no Logger instance set.
+     * The {@link LogManager LogManager} will be used to retrieve the Logger instance
+     * at every invocation of the monitor.
+     */
+    public Log4JComponentMonitor() {
+        delegate = new NullComponentMonitor();
+    }
+    
+    /**
+     * Creates a Log4JComponentMonitor with a given Logger instance class.
+     * The class name is used to retrieve the Logger instance.
+     *
+     * @param loggerClass the class of the Logger
+     */
+    public Log4JComponentMonitor(Class<?> loggerClass) {
+        this(loggerClass.getName());
+    }
+
+    /**
+     * Creates a Log4JComponentMonitor with a given Logger instance name. It uses the
+     * {@link org.apache.log4j.LogManager LogManager} to create the Logger instance.
+     *
+     * @param loggerName the name of the Log
+     */
+    public Log4JComponentMonitor(String loggerName) {
+        this(LogManager.getLogger(loggerName));
+    }
+
+    /**
+     * Creates a Log4JComponentMonitor with a given Logger instance
+     *
+     * @param logger the Logger to write to
+     */
+    public Log4JComponentMonitor(Logger logger) {
+        this();
+        this.logger = logger;
+    }
+
+    /**
+     * Creates a Log4JComponentMonitor with a given Logger instance class.
+     * The class name is used to retrieve the Logger instance.
+     *
+     * @param loggerClass the class of the Logger
+     * @param delegate the delegate
+     */
+    public Log4JComponentMonitor(Class<?> loggerClass, ComponentMonitor delegate) {
+        this(loggerClass.getName(), delegate);
+    }
+
+    /**
+     * Creates a Log4JComponentMonitor with a given Logger instance name. It uses the
+     * {@link org.apache.log4j.LogManager LogManager} to create the Logger instance.
+     *
+     * @param loggerName the name of the Log
+     * @param delegate the delegate
+     */
+    public Log4JComponentMonitor(String loggerName, ComponentMonitor delegate) {
+        this(LogManager.getLogger(loggerName), delegate);
+    }
+
+    /**
+     * Creates a Log4JComponentMonitor with a given Logger instance
+     *
+     * @param logger the Logger to write to
+     * @param delegate the delegate
+     */
+    public Log4JComponentMonitor(Logger logger, ComponentMonitor delegate) {
+        this(delegate);
+        this.logger = logger;
+    }
+
+    public Log4JComponentMonitor(ComponentMonitor delegate) {
+        this.delegate = delegate;
+    }
+
+    public <T> Constructor<T> instantiating(Container container, ComponentAdapter<T> componentAdapter,
+                                     Constructor<T> constructor
+    ) {
+        Logger logger = getLogger(constructor);
+        if (logger.isDebugEnabled()) {
+            logger.debug(format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor)));
+        }
+        return delegate.instantiating(container, componentAdapter, constructor);
+    }
+
+    public <T> void instantiated(Container container, ComponentAdapter<T> componentAdapter,
+                             Constructor<T> constructor,
+                             Object instantiated,
+                             Object[] parameters,
+                             long duration) {
+        Logger logger = getLogger(constructor);
+        if (logger.isDebugEnabled()) {
+            logger.debug(format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), duration, instantiated.getClass().getName(), parmsToString(parameters)));
+        }
+        delegate.instantiated(container, componentAdapter, constructor, instantiated, parameters, duration);
+    }
+
+    public <T> void instantiationFailed(Container container,
+                                    ComponentAdapter<T> componentAdapter,
+                                    Constructor<T> constructor,
+                                    Exception cause) {
+        Logger logger = getLogger(constructor);
+        if (logger.isEnabledFor(Priority.WARN)) {
+            logger.warn(format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), cause.getMessage()), cause);
+        }
+        delegate.instantiationFailed(container, componentAdapter, constructor, cause);
+    }
+
+    public void invoking(Container container,
+                         ComponentAdapter<?> componentAdapter,
+                         Member member,
+                         Object instance) {
+        Logger logger = getLogger(member);
+        if (logger.isDebugEnabled()) {
+            logger.debug(format(ComponentMonitorHelper.INVOKING, memberToString(member), instance));
+        }
+        delegate.invoking(container, componentAdapter, member, instance);
+    }
+
+    public void invoked(Container container,
+                        ComponentAdapter<?> componentAdapter,
+                        Method method,
+                        Object instance,
+                        long duration) {
+        Logger logger = getLogger(method);
+        if (logger.isDebugEnabled()) {
+            logger.debug(format(ComponentMonitorHelper.INVOKED, methodToString(method), instance, duration));
+        }
+        delegate.invoked(container, componentAdapter, method, instance, duration);
+    }
+
+    public void invocationFailed(Member member, Object instance, Exception cause) {
+        Logger logger = getLogger(member);
+        if (logger.isEnabledFor(Priority.WARN)) {
+            logger.warn(format(ComponentMonitorHelper.INVOCATION_FAILED, memberToString(member), instance, cause.getMessage()), cause);
+        }
+        delegate.invocationFailed(member, instance, cause);
+    }
+
+    public void lifecycleInvocationFailed(MutableContainer container,
+                                          ComponentAdapter<?> componentAdapter, Method method,
+                                          Object instance,
+                                          RuntimeException cause) {
+        Logger logger = getLogger(method);
+        if (logger.isEnabledFor(Priority.WARN)) {
+            logger.warn(format(ComponentMonitorHelper.LIFECYCLE_INVOCATION_FAILED, methodToString(method), instance, cause.getMessage()), cause);
+        }
+        delegate.lifecycleInvocationFailed(container, componentAdapter, method, instance, cause);
+    }
+
+    public Object noComponentFound(MutableContainer container, Object componentKey) {
+        Logger logger = this.logger != null ? this.logger : LogManager.getLogger(ComponentMonitor.class);
+        if (logger.isEnabledFor(Priority.WARN)) {
+            logger.warn(format(ComponentMonitorHelper.NO_COMPONENT, componentKey));
+        }
+        return delegate.noComponentFound(container, componentKey);
+
+    }
+
+    protected Logger getLogger(Member member) {
+        if ( logger != null ){
+            return logger;
+        } 
+        return LogManager.getLogger(member.getDeclaringClass());
+    }
+
+}

Added: incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/ComponentDependencyListener.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/ComponentDependencyListener.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/ComponentDependencyListener.java (added)
+++ incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/ComponentDependencyListener.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors.prefuse;
+
+import org.apache.composer.core.monitors.ComponentDependencyMonitor;
+
+
+/**
+ * Interprets dependency-related events.
+ * 
+ * @author Peter Barry
+ * @author Kent R. Spillner
+ */
+public interface ComponentDependencyListener {
+    public void addDependency(ComponentDependencyMonitor.Dependency dependency);
+}

Added: incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/DependencySet.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/DependencySet.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/DependencySet.java (added)
+++ incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/DependencySet.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors.prefuse;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.composer.core.monitors.ComponentDependencyMonitor.Dependency;
+
+/**
+ * Understands non-duplicated dependencies.
+ * 
+ * @author Peter Barry
+ * @author Kent R. Spillner
+ */
+public final class DependencySet implements ComponentDependencyListener {
+
+    private final Set uniqueDependencies = new HashSet();
+
+    private final ComponentDependencyListener listener;
+
+    public DependencySet(ComponentDependencyListener listener) {
+        this.listener = listener;
+    }
+
+    public void addDependency(Dependency dependency) {
+        if (uniqueDependencies.add(dependency)) {
+            listener.addDependency(dependency);
+        }
+    }
+
+    public Dependency[] getDependencies() {
+        return (Dependency[]) uniqueDependencies.toArray(new Dependency[uniqueDependencies.size()]);
+    }
+}

Added: incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/PrefuseDependencyGraph.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/PrefuseDependencyGraph.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/PrefuseDependencyGraph.java (added)
+++ incubator/composer/trunk/composer-core/src/main/java/org/apache/composer/core/monitors/prefuse/PrefuseDependencyGraph.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors.prefuse;
+
+import org.apache.composer.core.monitors.ComponentDependencyMonitor;
+import prefuse.data.Graph;
+import prefuse.data.Node;
+import prefuse.data.Schema;
+import prefuse.data.tuple.TupleSet;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public final class PrefuseDependencyGraph implements ComponentDependencyListener {
+    private Graph graph;
+
+    private final Map nodes;
+
+    public PrefuseDependencyGraph() {
+        this.graph = initializeGraph();
+        this.nodes = new HashMap();
+    }
+
+    public void addDependency(ComponentDependencyMonitor.Dependency dependency) {
+        Node componentNode = addNode(dependency.getComponentType());
+        Node dependencyNode = addNode(dependency.getDependencyType());
+        if (dependencyNode != null) {
+            graph.addEdge(componentNode, dependencyNode);
+        }
+    }
+
+    Collection getTypes() {
+        return nodes.keySet();
+    }
+
+    Node[] getNodes() {
+        return (Node[]) nodes.values().toArray(new Node[nodes.size()]);
+    }
+
+    private Node addNode(Class type) {
+        if (type != null && !nodes.containsKey(type)) {
+            Node node = graph.addNode();
+            node.set("type", type);
+            nodes.put(type, node);
+        }
+        return (Node) nodes.get(type);
+    }
+
+    private Graph initializeGraph() {
+        return getGraph(getSchema());
+    }
+
+    private Graph getGraph(Schema schema) {
+        graph = new Graph(true);
+        graph.addColumns(schema);
+        return graph;
+    }
+
+    private Schema getSchema() {
+        Schema schema = new Schema();
+        schema.addColumn("type", Class.class, null);
+        return schema;
+    }
+
+    public TupleSet getEdges() {
+        return graph.getEdges();
+    }
+
+    public Graph getGraph() {
+        return graph;
+    }
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentDependencyMonitorTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentDependencyMonitorTestCase.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentDependencyMonitorTestCase.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentDependencyMonitorTestCase.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.composer.core.monitors;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.composer.core.monitors.ComponentDependencyMonitor;
+import org.apache.composer.core.monitors.ComponentDependencyMonitor.Dependency;
+import org.apache.composer.core.monitors.prefuse.ComponentDependencyListener;
+import org.apache.composer.core.testmodel.DependsOnList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ComponentDependencyMonitorTestCase implements ComponentDependencyListener {
+    private ComponentDependencyMonitor monitor;
+
+    private Dependency dependency;
+
+    @Before
+    public void setUp() throws Exception {
+        monitor = new ComponentDependencyMonitor(this);
+        dependency = new Dependency(Object.class, String.class);
+    }
+
+    @Test public void testShouldDependOnList() throws Exception {
+        List list = new ArrayList();
+        DependsOnList dol = new DependsOnList(list);
+        monitor.instantiated(null, null, DependsOnList.class.getConstructors()[0], dol, new Object[] { list }, 10);
+        assertEquals(new Dependency(DependsOnList.class, ArrayList.class), dependency);
+    }
+
+    public void addDependency(Dependency dependency) {
+        this.dependency = dependency;
+    }
+
+    @Test public void testAShouldBeDependentOnB() throws Exception {
+        assertEquals(true, dependency.dependsOn(String.class));
+    }
+
+    @Test public void testADoesntDependOnB() throws Exception {
+        assertEquals(false, dependency.dependsOn(Boolean.class));
+    }
+
+    @Test public void testADoesntDependOnNullB() throws Exception {
+        assertEquals(false, dependency.dependsOn(null));
+    }
+
+    @Test public void testShouldNotEqualNull() throws Exception {
+        assertEquals("not equal to null", false, dependency.equals(null));
+    }
+
+    @Test public void testShouldEqualSelf() throws Exception {
+        assertEquals("equal to self", dependency, dependency);
+    }
+
+    @Test public void testShouldEqualSimilarDependency() throws Exception {
+        assertEquals(dependency, new Dependency(Object.class, String.class));
+    }
+
+    @Test public void testShouldNotEqualDifferentDependency() throws Exception {
+        assertEquals("not equal to different dependency", false, dependency.equals(new Dependency(Object.class,
+                Object.class)));
+        assertEquals("not equal to different dependency", false, dependency.equals(new Dependency(String.class,
+                String.class)));
+    }
+
+    @Test public void testShouldNotEqualObjectsWhichArentDependencies() throws Exception {
+        assertEquals("not equal to different type", false, dependency.equals(new Object()));
+    }
+
+    @Test public void testShouldNotThrowNullPointerExceptionsWhenComparingEmptyDependencies() throws Exception {
+        Dependency emptyDependency = new Dependency(null, null);
+        assertEquals("not equal to empty dependency", false, dependency.equals(emptyDependency));
+        assertEquals("not equal to empty dependency", false, emptyDependency.equals(dependency));
+    }
+
+    @Test public void testShouldNotThrowNullPointerExceptionsWhenComparingPartialDependencies() throws Exception {
+        Dependency partialDependency = new Dependency(Boolean.class, null);
+        assertEquals("not equal to empty dependency", false, dependency.equals(partialDependency));
+        assertEquals("not equal to empty dependency", false, partialDependency.equals(dependency));
+    }
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentMonitorHelperTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentMonitorHelperTestCase.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentMonitorHelperTestCase.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ComponentMonitorHelperTestCase.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.monitors.ComponentMonitorHelper;
+import static org.apache.composer.core.monitors.ComponentMonitorHelper.*;
+import org.apache.composer.core.monitors.ForTestSakeAppender;
+import static org.junit.Assert.assertTrue;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Paul Hammant
+ * @author Aslak Helles&oslash;y
+ * @author Mauro Talevi
+ * @author Juze Peleteiro
+ */
+public abstract class ComponentMonitorHelperTestCase {
+    private ComponentMonitor componentMonitor;
+    private Constructor constructor;
+    private Method method;
+    
+    @Before
+    public void setUp() throws Exception {
+        constructor = getConstructor();
+        method = getMethod();
+        componentMonitor = makeComponentMonitor();
+    }
+
+    protected abstract ComponentMonitor makeComponentMonitor();
+    
+    protected abstract Constructor getConstructor() throws NoSuchMethodException;
+
+    protected abstract Method getMethod() throws NoSuchMethodException;
+    
+    protected abstract String getLogPrefix();
+
+    protected void tearDown() throws Exception {
+    	ForTestSakeAppender.CONTENT = "";
+    }
+
+    @Test public void testShouldTraceInstantiating() throws IOException {
+        componentMonitor.instantiating(null, null, constructor);
+        assertFileContent(getLogPrefix() + ComponentMonitorHelper.format(ComponentMonitorHelper.INSTANTIATING, ctorToString(constructor)));
+    }
+
+    @Test public void testShouldTraceInstantiatedWithInjected() throws IOException {
+        Object[] injected = new Object[0];
+        Object instantiated = new Object();
+        componentMonitor.instantiated(null, null, constructor, instantiated, injected, 543);
+        String s = ComponentMonitorHelper.format(ComponentMonitorHelper.INSTANTIATED, ctorToString(constructor), (long) 543, instantiated.getClass().getName(), parmsToString(injected));
+        assertFileContent(getLogPrefix() + s);
+    }
+
+
+    @Test public void testShouldTraceInstantiationFailed() throws IOException {
+        componentMonitor.instantiationFailed(null, null, constructor, new RuntimeException("doh"));
+        assertFileContent(getLogPrefix() + ComponentMonitorHelper.format(ComponentMonitorHelper.INSTANTIATION_FAILED, ctorToString(constructor), "doh"));
+    }
+
+    @Test public void testShouldTraceInvoking() throws IOException {
+        componentMonitor.invoking(null, null, method, this);
+        assertFileContent(getLogPrefix() + ComponentMonitorHelper.format(ComponentMonitorHelper.INVOKING, methodToString(method), this));
+    }
+
+    @Test public void testShouldTraceInvoked() throws IOException {
+        componentMonitor.invoked(null, null, method, this, 543);
+        assertFileContent(getLogPrefix() + ComponentMonitorHelper.format(ComponentMonitorHelper.INVOKED, methodToString(method), this, (long) 543));
+    }
+
+    @Test public void testShouldTraceInvocatiationFailed() throws IOException {
+        componentMonitor.invocationFailed(method, this, new RuntimeException("doh"));
+        assertFileContent(getLogPrefix() + ComponentMonitorHelper.format(ComponentMonitorHelper.INVOCATION_FAILED, methodToString(method), this, "doh"));
+    }
+
+    @Test public void testShouldTraceNoComponent() throws IOException {
+        componentMonitor.noComponentFound(null, "doh");
+        assertFileContent(getLogPrefix() + ComponentMonitorHelper.format(ComponentMonitorHelper.NO_COMPONENT, "doh"));
+    }
+
+
+    protected void assertFileContent(String line) throws IOException{
+        List lines = toLines( new StringReader( ForTestSakeAppender.CONTENT ) );
+        String s = lines.toString();
+        assertTrue("Line '" + line + "' not found", s.indexOf(line) > 0);
+    }
+    
+    protected List toLines(Reader resource) throws IOException {
+        BufferedReader br = new BufferedReader(resource);
+        List lines = new ArrayList();
+        String line = br.readLine();
+        while ( line != null) {
+            lines.add(line);
+            line = br.readLine();
+        }
+        return lines;
+    } 
+
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitorTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitorTestCase.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitorTestCase.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/DotDependencyGraphComponentMonitorTestCase.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,87 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.testmodel.DependsOnDependsOnListAndVector;
+import org.apache.composer.core.testmodel.DependsOnList;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Vector;
+
+public class DotDependencyGraphComponentMonitorTestCase {
+
+    DotDependencyGraphComponentMonitor monitor;
+
+    @Before
+    public void setUp() throws Exception {
+        monitor = new DotDependencyGraphComponentMonitor();
+
+        Vector vec = new Vector();
+        List list = new ArrayList();
+        DependsOnList dol = new DependsOnList(list);
+        DependsOnDependsOnListAndVector dodolav = new DependsOnDependsOnListAndVector(vec, dol);
+
+        monitor.instantiated(null, null, Vector.class.getConstructor(), vec, new Object[]{}, 8);
+        monitor.instantiated(null,
+                             null, ArrayList.class.getConstructor(Collection.class), list, new Object[]{vec}, 12);
+        monitor.instantiated(null, null, DependsOnList.class.getConstructors()[0], dol, new Object[]{list}, 10);
+        monitor.instantiated(null,
+                             null,
+                             DependsOnDependsOnListAndVector.class.getConstructors()[0], dodolav, new Object[]{vec, dol}, 16);
+        monitor.instantiated(null,
+                             null,
+                             DependsOnDependsOnListAndVector.class.getConstructors()[0], dodolav, new Object[]{vec, dol}, 12);
+        monitor.instantiated(null,
+                             null,
+                             DependsOnDependsOnListAndVector.class.getConstructors()[0], dodolav, new Object[]{vec, dol}, 9);
+    }
+
+    @Test public void testSimpleClassDependencyGraphCanEliminateDupes() throws NoSuchMethodException {
+        String expected = ("" +
+                "  'java.util.ArrayList' -> 'java.util.Vector';\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnDependsOnListAndVector' -> 'java.util.Vector';\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnDependsOnListAndVector' -> 'org.apache.composer.core.testmodel.DependsOnList';\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnList' -> 'java.util.ArrayList';\n" +
+                "").replaceAll("'","\"");
+        assertEquals(expected, monitor.getClassDependencyGraph());
+    }
+
+    @Test public void testSimpleInterfaceDependencyGraphCanEliminateDupes() throws NoSuchMethodException {
+        String expected = ("" +
+                "  'java.util.ArrayList' -> 'java.util.Collection' [style=dotted,label='needs'];\n" +
+                "  'java.util.ArrayList' -> 'java.util.List' [style=dotted, color=red,label='isA'];\n" +
+                "  'java.util.ArrayList' [label='ArrayList\\njava.util'];\n" +
+                "  'java.util.Collection' [shape=box, label='Collection\\njava.util'];\n" +
+                "  'java.util.List' [shape=box, label='List\\njava.util'];\n" +
+                "  'java.util.Vector' -> 'java.util.Collection' [style=dotted, color=red,label='isA'];\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnDependsOnListAndVector' -> 'java.util.Vector' [label='needs'];\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnDependsOnListAndVector' -> 'org.apache.composer.core.testmodel.DependsOnList' [label='needs'];\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnDependsOnListAndVector' [label='DependsOnDependsOnListAndVector\\norg.apache.composer.core.testmodel'];\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnList' -> 'java.util.List' [style=dotted,label='needs'];\n" +
+                "  'org.apache.composer.core.testmodel.DependsOnList' [label='DependsOnList\\norg.apache.composer.core.testmodel'];\n" +
+                "").replaceAll("'","\"");
+        String interfaceDependencyGraph = monitor.getInterfaceDependencyGraph();
+        assertEquals(expected, interfaceDependencyGraph);
+    }
+
+
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ForTestSakeAppender.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ForTestSakeAppender.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ForTestSakeAppender.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/ForTestSakeAppender.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.log4j.Appender;
+import org.apache.log4j.Layout;
+import org.apache.log4j.spi.ErrorHandler;
+import org.apache.log4j.spi.Filter;
+import org.apache.log4j.spi.LoggingEvent;
+
+/**
+ * @author Juze Peleteiro
+ */
+public class ForTestSakeAppender implements Appender {
+
+	public static String CONTENT = "";
+
+	private String name;
+
+	private Layout layout;
+
+	private ErrorHandler errorHandler;
+
+	public void addFilter(Filter filter) {
+	}
+	
+	public ForTestSakeAppender() {
+		CONTENT = "";
+	}
+	
+	/**
+	 * @see org.apache.log4j.Appender#getFilter()
+	 */
+	public Filter getFilter() {
+		return null;
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#clearFilters()
+	 */
+	public void clearFilters() {
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#close()
+	 */
+	public void close() {
+		CONTENT = "";
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#doAppend(org.apache.log4j.spi.LoggingEvent)
+	 */
+	public void doAppend(LoggingEvent e) {
+		CONTENT += "\n" + layout.format(e);
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#getName()
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#setErrorHandler(org.apache.log4j.spi.ErrorHandler)
+	 */
+	public void setErrorHandler(ErrorHandler value) {
+		errorHandler = value;
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#getErrorHandler()
+	 */
+	public ErrorHandler getErrorHandler() {
+		return errorHandler;
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#setLayout(org.apache.log4j.Layout)
+	 */
+	public void setLayout(Layout value) {
+		layout = value;
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#getLayout()
+	 */
+	public Layout getLayout() {
+		return layout;
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#setName(java.lang.String)
+	 */
+	public void setName(String value) {
+		name = value;
+	}
+
+	/**
+	 * @see org.apache.log4j.Appender#requiresLayout()
+	 */
+	public boolean requiresLayout() {
+		return true;
+	}
+
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerCommonsLoggingComponentMonitorTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerCommonsLoggingComponentMonitorTestCase.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerCommonsLoggingComponentMonitorTestCase.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerCommonsLoggingComponentMonitorTestCase.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.monitors.CommonsLoggingComponentMonitor;
+import org.apache.composer.core.monitors.ComponentMonitorHelperTestCase;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class MultipleLoggerCommonsLoggingComponentMonitorTestCase extends ComponentMonitorHelperTestCase {
+
+    String logPrefixName = String.class.getName();
+
+    protected ComponentMonitor makeComponentMonitor() {
+        return new CommonsLoggingComponentMonitor();
+    }
+
+    protected Method getMethod() throws NoSuchMethodException {
+        return String.class.getMethod("toString");
+    }
+
+    protected Constructor getConstructor() {
+        return String.class.getConstructors()[0];
+    }
+
+    protected String getLogPrefix() {
+        return "[" + logPrefixName + "] ";
+    }
+
+    public void testShouldTraceNoComponent() throws IOException {
+        logPrefixName = ComponentMonitor.class.getName();
+        super.testShouldTraceNoComponent();
+    }
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerLog4JComponentMonitorTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerLog4JComponentMonitorTestCase.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerLog4JComponentMonitorTestCase.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/MultipleLoggerLog4JComponentMonitorTestCase.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.monitors.ComponentMonitorHelperTestCase;
+import org.apache.composer.core.monitors.Log4JComponentMonitor;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/**
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public class MultipleLoggerLog4JComponentMonitorTestCase extends ComponentMonitorHelperTestCase {
+
+    String logPrefixName = String.class.getName();
+
+    protected ComponentMonitor makeComponentMonitor() {
+        return new Log4JComponentMonitor();
+    }
+
+    protected Method getMethod() throws NoSuchMethodException {
+        return String.class.getMethod("toString");
+    }
+
+    protected Constructor getConstructor() {
+        return String.class.getConstructors()[0];
+    }
+
+    protected String getLogPrefix() {
+        return "[" + logPrefixName + "] ";
+    }
+
+    public void testShouldTraceNoComponent() throws IOException {
+        logPrefixName = ComponentMonitor.class.getName();
+        super.testShouldTraceNoComponent();
+    }
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerCommonsLoggingComponentMonitorTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerCommonsLoggingComponentMonitorTestCase.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerCommonsLoggingComponentMonitorTestCase.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerCommonsLoggingComponentMonitorTestCase.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.monitors.CommonsLoggingComponentMonitor;
+import org.apache.composer.core.monitors.ComponentMonitorHelperTestCase;
+import org.junit.Test;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.io.IOException;
+
+public class SingleLoggerCommonsLoggingComponentMonitorTestCase extends ComponentMonitorHelperTestCase {
+
+    protected ComponentMonitor makeComponentMonitor() {
+        return new CommonsLoggingComponentMonitor(CommonsLoggingComponentMonitor.class);
+    }
+
+    protected Constructor getConstructor() throws NoSuchMethodException {
+        return getClass().getConstructor((Class[])null);
+    }
+
+    protected Method getMethod() throws NoSuchMethodException {
+        return getClass().getDeclaredMethod("makeComponentMonitor", (Class[])null);
+    }
+
+    protected String getLogPrefix() {
+        return "[" + CommonsLoggingComponentMonitor.class.getName() + "] ";
+    }
+
+    @Test
+    public void testShouldTraceInstantiating() throws IOException {
+        super.testShouldTraceInstantiating();   
+    }
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerLog4JComponentMonitorTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerLog4JComponentMonitorTestCase.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerLog4JComponentMonitorTestCase.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/SingleLoggerLog4JComponentMonitorTestCase.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.composer.core.monitors;
+
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.monitors.ComponentMonitorHelperTestCase;
+import org.apache.composer.core.monitors.Log4JComponentMonitor;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+/**
+ * @author Paul Hammant
+ * @author Mauro Talevi
+ */
+public class SingleLoggerLog4JComponentMonitorTestCase extends ComponentMonitorHelperTestCase {
+
+    protected ComponentMonitor makeComponentMonitor() {
+        return new Log4JComponentMonitor(Log4JComponentMonitor.class);
+    }
+
+    protected Constructor getConstructor() throws NoSuchMethodException {
+        return getClass().getConstructor((Class[])null);
+    }
+
+    protected Method getMethod() throws NoSuchMethodException {
+        return getClass().getDeclaredMethod("makeComponentMonitor", (Class[])null);
+    }
+
+    protected String getLogPrefix() {
+        return "[" + Log4JComponentMonitor.class.getName() + "] ";
+    }
+
+    public void testShouldTraceNoComponent() throws IOException {
+        super.testShouldTraceNoComponent();    
+    }
+}

Added: incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/AggregateDemoHacks.java
URL: http://svn.apache.org/viewvc/incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/AggregateDemoHacks.java?rev=618168&view=auto
==============================================================================
--- incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/AggregateDemoHacks.java (added)
+++ incubator/composer/trunk/composer-core/src/test/java/org/apache/composer/core/monitors/prefuse/AggregateDemoHacks.java Sun Feb  3 20:17:59 2008
@@ -0,0 +1,409 @@
+package org.picocontainer.gems.monitors.prefuse;
+
+import java.awt.Cursor;
+import java.awt.event.MouseEvent;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import prefuse.Constants;
+import prefuse.Display;
+import prefuse.Visualization;
+import prefuse.action.ActionList;
+import prefuse.action.RepaintAction;
+import prefuse.action.assignment.ColorAction;
+import prefuse.action.assignment.DataColorAction;
+import prefuse.action.layout.Layout;
+import prefuse.action.layout.graph.ForceDirectedLayout;
+import prefuse.activity.Activity;
+import prefuse.controls.ControlAdapter;
+import prefuse.controls.PanControl;
+import prefuse.controls.ZoomControl;
+import prefuse.data.Graph;
+import prefuse.render.DefaultRendererFactory;
+import prefuse.render.EdgeRenderer;
+import prefuse.render.LabelRenderer;
+import prefuse.render.PolygonRenderer;
+import prefuse.render.Renderer;
+import prefuse.util.ColorLib;
+import prefuse.util.GraphicsLib;
+import prefuse.visual.AggregateItem;
+import prefuse.visual.AggregateTable;
+import prefuse.visual.EdgeItem;
+import prefuse.visual.VisualGraph;
+import prefuse.visual.VisualItem;
+
+/**
+ * Demo application showcasing the use of AggregateItems to visualize groupings
+ * of nodes with in a graph visualization.
+ * 
+ * This class uses the AggregateLayout class to compute bounding polygons for
+ * each aggregate and the AggregateDragControl to enable drags of both nodes and
+ * node aggregates.
+ * 
+ * @author <a href="http://jheer.org">jeffrey heer</a>
+ */
+public class AggregateDemoHacks extends Display {
+    private static final int LIGHT_BLUE = ColorLib.rgba(200, 200, 255, 150);
+
+    private static final int LIGHT_GREEN = ColorLib.rgba(200, 255, 200, 150);
+
+    private static final int LIGHT_RED = ColorLib.rgba(255, 200, 200, 150);
+
+    private static final int WHITE = ColorLib.gray(255);
+
+    private static final String GRAPH = "graph";
+
+    private static final String NODES = "graph.nodes";
+
+    private static final String EDGES = "graph.edges";
+
+    private static final String EDGE_HEADS = "graph.edges.arrowheads";
+
+    private static final String AGGR = "aggregates";
+
+    private final int BLACK = ColorLib.gray(0);
+
+    public AggregateDemoHacks(Graph g) throws IOException {
+
+        super(new Visualization());
+        initDataGroups(g);
+
+        Renderer polyR = new PolygonRenderer(Constants.POLY_TYPE_CURVE);
+        ((PolygonRenderer) polyR).setCurveSlack(0.15f);
+
+        LabelRenderer labelRenderer = new LabelRenderer("type");
+        labelRenderer.setRoundedCorner(8, 8);
+
+        EdgeRenderer edgeRenderer = new EdgeRenderer(Constants.EDGE_TYPE_LINE);
+
+        DefaultRendererFactory drf = new DefaultRendererFactory(labelRenderer);
+        drf.add("ingroup('aggregates')", polyR);
+        drf.add("ingroup('aggregates')", labelRenderer);
+        drf.setDefaultEdgeRenderer(edgeRenderer);
+        m_vis.setRendererFactory(drf);
+
+        ActionList layout = buildActionList();
+        m_vis.putAction("layout", layout);
+
+        setSize(500, 500);
+        pan(250, 250);
+        setHighQuality(true);
+        addControlListener(new AggregateDragControl());
+        addControlListener(new ZoomControl());
+        addControlListener(new PanControl());
+
+        m_vis.run("layout");
+    }
+
+    private ActionList buildColorActionList() {
+        ColorAction nStroke = new ColorAction(NODES, VisualItem.STROKECOLOR);
+        nStroke.setDefaultColor(ColorLib.gray(100));
+        nStroke.add("_hover", ColorLib.gray(50));
+
+        ColorAction nFill = new ColorAction(NODES, VisualItem.FILLCOLOR);
+        nFill.setDefaultColor(WHITE);
+        nFill.add("_hover", ColorLib.gray(200));
+
+        ColorAction nEdges = new ColorAction(EDGES, VisualItem.STROKECOLOR);
+        nEdges.setDefaultColor(ColorLib.gray(100));
+        ColorAction nEdgesHeads = new ColorAction(EDGES, VisualItem.FILLCOLOR);
+        nEdgesHeads.setDefaultColor(ColorLib.gray(100));
+
+        ColorAction classNames = new ColorAction(NODES, VisualItem.TEXTCOLOR);
+        classNames.setDefaultColor(BLACK);
+
+        ColorAction aStroke = new ColorAction(AGGR, VisualItem.STROKECOLOR);
+        aStroke.setDefaultColor(ColorLib.gray(200));
+        aStroke.add("_hover", ColorLib.rgb(255, 100, 100));
+
+        int[] palette = new int[] { LIGHT_RED, LIGHT_GREEN, LIGHT_BLUE };
+        ColorAction aFill = new DataColorAction(AGGR, "type", Constants.NOMINAL, VisualItem.FILLCOLOR, palette);
+
+        // bundle the color actions
+        ActionList colors = new ActionList();
+        colors.add(classNames);
+        colors.add(nStroke);
+        colors.add(nFill);
+        colors.add(nEdges);
+        colors.add(nEdgesHeads);
+        colors.add(aStroke);
+        colors.add(aFill);
+        return colors;
+    }
+
+    private ActionList buildActionList() {
+        ActionList colors = buildColorActionList();
+        ActionList all = new ActionList(Activity.INFINITY);
+        all.add(colors);
+        all.add(new ForceDirectedLayout(GRAPH) {
+            protected float getSpringLength(EdgeItem e) {
+                return -0.3f;
+            }
+
+            protected float getMassValue(VisualItem n) {
+                return 5.0f;
+            }
+        });
+
+        all.add(new AggregateLayout(AGGR));
+        all.add(new RepaintAction());
+        return all;
+    }
+
+    private void initDataGroups(Graph graph) {
+
+        VisualGraph vg = m_vis.addGraph(GRAPH, graph);
+        m_vis.setInteractive(EDGES, null, false);
+        m_vis.setValue(NODES, null, VisualItem.SHAPE, Constants.SHAPE_ELLIPSE);
+
+        AggregateTable at = m_vis.addAggregates(AGGR);
+        at.addColumn(VisualItem.POLYGON, float[].class);
+        at.addColumn("type", String.class);
+
+        System.out.println("Aggregating...");
+        Map aggregates = new HashMap();
+        Iterator nodes = vg.nodes();
+        while (nodes.hasNext()) {
+            VisualItem node = (VisualItem) nodes.next();
+            String pkg = node.getString("type");
+            System.out.println(pkg);
+            if (!aggregates.containsKey(pkg)) {
+                AggregateItem aggregate = (AggregateItem) at.addItem();
+                aggregate.setString("type", pkg);
+                aggregates.put(pkg, aggregate);
+            }
+            AggregateItem aggregate = (AggregateItem) aggregates.get(pkg);
+            aggregate.addItem(node);
+        }
+        System.out.println("done!");
+    }
+
+    public static JFrame demo(Graph graph) throws IOException {
+        AggregateDemoHacks ad = new AggregateDemoHacks(graph);
+        JFrame frame = new JFrame("p r e f u s e  |  a g g r e g a t e d");
+        frame.getContentPane().add(ad);
+        frame.pack();
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        frame.setVisible(true);
+        return frame;
+    }
+
+} // end of class AggregateDemo
+
+/**
+ * Layout algorithm that computes a convex hull surrounding aggregate items and
+ * saves it in the "_polygon" field.
+ */
+final class AggregateLayout extends Layout {
+
+    private final int m_margin = 5; // convex hull pixel margin
+
+    private double[] m_pts; // buffer for computing convex hulls
+
+    public AggregateLayout(String aggrGroup) {
+        super(aggrGroup);
+    }
+
+    /**
+     * @see edu.berkeley.guir.prefuse.action.Action#run(edu.berkeley.guir.prefuse.ItemRegistry,
+     *      double)
+     */
+    public void run(double frac) {
+
+        AggregateTable aggr = (AggregateTable) m_vis.getGroup(m_group);
+        // do we have any to process?
+        int num = aggr.getTupleCount();
+        if (num == 0)
+            return;
+
+        // update buffers
+        int maxsz = 0;
+        for (Iterator aggrs = aggr.tuples(); aggrs.hasNext();)
+            maxsz = Math.max(maxsz, 4 * 2 * ((AggregateItem) aggrs.next()).getAggregateSize());
+        if (m_pts == null || maxsz > m_pts.length) {
+            m_pts = new double[maxsz];
+        }
+
+        // compute and assign convex hull for each aggregate
+        Iterator aggrs = m_vis.visibleItems(m_group);
+        while (aggrs.hasNext()) {
+            AggregateItem aitem = (AggregateItem) aggrs.next();
+
+            int idx = 0;
+            if (aitem.getAggregateSize() == 0)
+                continue;
+            VisualItem item;
+            Iterator iter = aitem.items();
+            while (iter.hasNext()) {
+                item = (VisualItem) iter.next();
+                if (item.isVisible()) {
+                    addPoint(m_pts, idx, item, m_margin);
+                    idx += 2 * 4;
+                }
+            }
+            // if no aggregates are visible, do nothing
+            if (idx == 0)
+                continue;
+
+            // compute convex hull
+            double[] nhull = GraphicsLib.convexHull(m_pts, idx);
+
+            // prepare viz attribute array
+            float[] fhull = (float[]) aitem.get(VisualItem.POLYGON);
+            if (fhull == null || fhull.length < nhull.length)
+                fhull = new float[nhull.length];
+            else if (fhull.length > nhull.length)
+                fhull[nhull.length] = Float.NaN;
+
+            // copy hull values
+            for (int j = 0; j < nhull.length; j++)
+                fhull[j] = (float) nhull[j];
+            aitem.set(VisualItem.POLYGON, fhull);
+            aitem.setValidated(false); // force invalidation
+        }
+    }
+
+    private static void addPoint(double[] pts, int idx, VisualItem item, int growth) {
+        Rectangle2D b = item.getBounds();
+        double minX = (b.getMinX()) - growth, minY = (b.getMinY()) - growth;
+        double maxX = (b.getMaxX()) + growth, maxY = (b.getMaxY()) + growth;
+        pts[idx] = minX;
+        pts[idx + 1] = minY;
+        pts[idx + 2] = minX;
+        pts[idx + 3] = maxY;
+        pts[idx + 4] = maxX;
+        pts[idx + 5] = minY;
+        pts[idx + 6] = maxX;
+        pts[idx + 7] = maxY;
+    }
+
+} // end of class AggregateLayout
+
+/**
+ * Interactive drag control that is "aggregate-aware"
+ */
+final class AggregateDragControl extends ControlAdapter {
+
+    private VisualItem activeItem;
+
+    protected final Point2D down = new Point2D.Double();
+
+    protected final Point2D temp = new Point2D.Double();
+
+    protected boolean dragged;
+
+    /**
+     * Creates a new drag control that issues repaint requests as an item is
+     * dragged.
+     */
+    public AggregateDragControl() {
+    }
+
+    /**
+     * @see prefuse.controls.Control#itemEntered(prefuse.visual.VisualItem,
+     *      java.awt.event.MouseEvent)
+     */
+    public void itemEntered(VisualItem item, MouseEvent e) {
+        Display d = (Display) e.getSource();
+        d.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+        activeItem = item;
+        if (!(item instanceof AggregateItem))
+            setFixed(item, true);
+    }
+
+    /**
+     * @see prefuse.controls.Control#itemExited(prefuse.visual.VisualItem,
+     *      java.awt.event.MouseEvent)
+     */
+    public void itemExited(VisualItem item, MouseEvent e) {
+        if (activeItem == item) {
+            activeItem = null;
+            setFixed(item, false);
+        }
+        Display d = (Display) e.getSource();
+        d.setCursor(Cursor.getDefaultCursor());
+    }
+
+    /**
+     * @see prefuse.controls.Control#itemPressed(prefuse.visual.VisualItem,
+     *      java.awt.event.MouseEvent)
+     */
+    public void itemPressed(VisualItem item, MouseEvent e) {
+        if (!SwingUtilities.isLeftMouseButton(e))
+            return;
+        dragged = false;
+        Display d = (Display) e.getComponent();
+        d.getAbsoluteCoordinate(e.getPoint(), down);
+        if (item instanceof AggregateItem)
+            setFixed(item, true);
+    }
+
+    /**
+     * @see prefuse.controls.Control#itemReleased(prefuse.visual.VisualItem,
+     *      java.awt.event.MouseEvent)
+     */
+    public void itemReleased(VisualItem item, MouseEvent e) {
+        if (!SwingUtilities.isLeftMouseButton(e))
+            return;
+        if (dragged) {
+            activeItem = null;
+            setFixed(item, false);
+            dragged = false;
+        }
+    }
+
+    /**
+     * @see prefuse.controls.Control#itemDragged(prefuse.visual.VisualItem,
+     *      java.awt.event.MouseEvent)
+     */
+    public void itemDragged(VisualItem item, MouseEvent e) {
+        if (!SwingUtilities.isLeftMouseButton(e))
+            return;
+        dragged = true;
+        Display d = (Display) e.getComponent();
+        d.getAbsoluteCoordinate(e.getPoint(), temp);
+        double dx = temp.getX() - down.getX();
+        double dy = temp.getY() - down.getY();
+
+        move(item, dx, dy);
+
+        down.setLocation(temp);
+    }
+
+    protected static void setFixed(VisualItem item, boolean fixed) {
+        if (item instanceof AggregateItem) {
+            Iterator items = ((AggregateItem) item).items();
+            while (items.hasNext()) {
+                setFixed((VisualItem) items.next(), fixed);
+            }
+        } else {
+            item.setFixed(fixed);
+        }
+    }
+
+    protected static void move(VisualItem item, double dx, double dy) {
+        if (item instanceof AggregateItem) {
+            Iterator items = ((AggregateItem) item).items();
+            while (items.hasNext()) {
+                move((VisualItem) items.next(), dx, dy);
+            }
+        } else {
+            double x = item.getX();
+            double y = item.getY();
+            item.setStartX(x);
+            item.setStartY(y);
+            item.setX(x + dx);
+            item.setY(y + dy);
+            item.setEndX(x + dx);
+            item.setEndY(y + dy);
+        }
+    }
+
+} // end of class AggregateDragControl



Mime
View raw message