components/visual-panels/core/src/java/util/com/oracle/solaris/vp/util/misc/DebugUtil.java
changeset 3553 f1d133b09a8c
parent 3552 077ebe3d0d24
child 3554 ef58713bafc4
equal deleted inserted replaced
3552:077ebe3d0d24 3553:f1d133b09a8c
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     4  * The contents of this file are subject to the terms of the
       
     5  * Common Development and Distribution License (the "License").
       
     6  * You may not use this file except in compliance with the License.
       
     7  *
       
     8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
     9  * or http://www.opensolaris.org/os/licensing.
       
    10  * See the License for the specific language governing permissions
       
    11  * and limitations under the License.
       
    12  *
       
    13  * When distributing Covered Code, include this CDDL HEADER in each
       
    14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    15  * If applicable, add the following below this CDDL HEADER, with the
       
    16  * fields enclosed by brackets "[]" replaced with your own identifying
       
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
       
    18  *
       
    19  * CDDL HEADER END
       
    20  */
       
    21 
       
    22 /*
       
    23  * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
       
    24  */
       
    25 
       
    26 package com.oracle.solaris.vp.util.misc;
       
    27 
       
    28 import java.awt.*;
       
    29 import java.awt.event.*;
       
    30 import java.beans.*;
       
    31 import java.io.PrintWriter;
       
    32 import java.util.*;
       
    33 import java.util.List;
       
    34 
       
    35 public class DebugUtil {
       
    36     //
       
    37     // Inner classes
       
    38     //
       
    39 
       
    40     public static interface ComponentHandler {
       
    41 	void handle(Component comp);
       
    42     }
       
    43 
       
    44     public static interface DumpHandler {
       
    45 	/**
       
    46 	 * Dumps some text representation of the given object to the given
       
    47 	 * {@code PrintWriter}.
       
    48 	 *
       
    49 	 * @param	object
       
    50 	 *		the object to dump
       
    51 	 *
       
    52 	 * @param	indent
       
    53 	 *		the indent to use when writing to the given {@code
       
    54 	 *		PrintWriter}
       
    55 	 *
       
    56 	 * @param	title
       
    57 	 *		the String prefix to prepend to the output
       
    58 	 *
       
    59 	 * @param	out
       
    60 	 *		the {@code PrintWriter} to which to write
       
    61 	 *
       
    62 	 * @return	{@code true} if this {@code DumpHandler} successfully
       
    63 	 *		handled the given object, {@code false} otherwise
       
    64 	 */
       
    65 	boolean dump(String title, Object object, int indent, PrintWriter out);
       
    66     }
       
    67 
       
    68     //
       
    69     // Static data
       
    70     //
       
    71 
       
    72     public static final DumpHandler defaultHandler =
       
    73 	new DumpHandler() {
       
    74 	    @Override
       
    75 	    public boolean dump(String title, Object object, int indent,
       
    76 		PrintWriter out) {
       
    77 
       
    78 		out.printf("%s%s%s\n", indent(indent), title, object);
       
    79 		return true;
       
    80 	    }
       
    81 	};
       
    82 
       
    83     public static final DumpHandler collectionHandler =
       
    84 	new DumpHandler() {
       
    85 	    @Override
       
    86 	    public boolean dump(String title, Object object, int indent,
       
    87 		PrintWriter out) {
       
    88 
       
    89 		if (object instanceof Collection) {
       
    90 		    Collection collection = (Collection)object;
       
    91 		    out.printf("%s%s%s (%d elements)\n", indent(indent),
       
    92 			title, toBaseName(object), collection.size());
       
    93 
       
    94 		    indent++;
       
    95 
       
    96 		    int i = 0;
       
    97 		    for (Object value : collection) {
       
    98 			String subPrefix = String.format("%d. ", i++);
       
    99 			DebugUtil.dump(subPrefix, value, indent, out);
       
   100 		    }
       
   101 		    return true;
       
   102 		}
       
   103 
       
   104 		return false;
       
   105 	    }
       
   106 	};
       
   107 
       
   108     public static final DumpHandler mapHandler =
       
   109 	new DumpHandler() {
       
   110 	    @Override
       
   111 	    public boolean dump(String title, Object object, int indent,
       
   112 		PrintWriter out) {
       
   113 
       
   114 		if (object instanceof Map) {
       
   115 		    Map map = (Map)object;
       
   116 		    out.printf("%s%s%s (%d elements)\n", indent(indent),
       
   117 			title, toBaseName(object), map.size());
       
   118 
       
   119 		    indent++;
       
   120 
       
   121 		    int i = 0;
       
   122 		    for (Object key : map.keySet()) {
       
   123 			Object value = map.get(key);
       
   124 			String subPrefix = String.format("%d. %s = ", i++, key);
       
   125 			DebugUtil.dump(subPrefix, value, indent, out);
       
   126 		    }
       
   127 		    return true;
       
   128 		}
       
   129 
       
   130 		return false;
       
   131 	    }
       
   132 	};
       
   133 
       
   134     public static final DumpHandler componentHandler =
       
   135 	new DumpHandler() {
       
   136 	    @Override
       
   137 	    public boolean dump(String title, Object object, int indent,
       
   138 		PrintWriter out) {
       
   139 
       
   140 		if (object instanceof Component) {
       
   141 		    Component comp = (Component)object;
       
   142 		    String text = getText(comp);
       
   143 		    text = text == null ? "" : (": \"" + text + "\"");
       
   144 
       
   145 		    out.printf("%s%s%s%s\n", indent(indent), title,
       
   146 			toBaseName(object), text);
       
   147 
       
   148 		    return true;
       
   149 		}
       
   150 
       
   151 		return false;
       
   152 	    }
       
   153 
       
   154 	    //
       
   155 	    // Private methods
       
   156 	    //
       
   157 
       
   158 	    private String getText(Component comp) {
       
   159 		try {
       
   160 		    return (String)comp.getClass().getMethod("getText").invoke(
       
   161 			comp);
       
   162 		} catch (Throwable e) {
       
   163 		}
       
   164 		return null;
       
   165 	    }
       
   166 	};
       
   167 
       
   168     public static final List<DumpHandler> handlers =
       
   169 	new ArrayList<DumpHandler>();
       
   170 
       
   171     static {
       
   172 	handlers.add(defaultHandler);
       
   173 	handlers.add(collectionHandler);
       
   174 	handlers.add(mapHandler);
       
   175 	handlers.add(componentHandler);
       
   176     }
       
   177 
       
   178     private static final int _INDENTSIZE = 2;
       
   179 
       
   180     //
       
   181     // Static methods
       
   182     //
       
   183 
       
   184     public static void addComponentHandler(
       
   185 	Component comp, final ComponentHandler handler) {
       
   186 
       
   187 	AWTEventListener listener =
       
   188 	    new AWTEventListener() {
       
   189 		@Override
       
   190 		public void eventDispatched(AWTEvent event) {
       
   191 		    MouseEvent e = (MouseEvent)event;
       
   192 		    if (e.getID() == MouseEvent.MOUSE_CLICKED &&
       
   193 			e.getButton() == 2 && e.getClickCount() == 1) {
       
   194 			handler.handle((Component)e.getSource());
       
   195 		    }
       
   196 		}
       
   197 	    };
       
   198 	Toolkit.getDefaultToolkit().addAWTEventListener(
       
   199 	    listener, AWTEvent.MOUSE_EVENT_MASK);
       
   200     }
       
   201 
       
   202     public static void dump(Object object) {
       
   203 	dump("", object);
       
   204     }
       
   205 
       
   206     public static void dump(String title, Object object) {
       
   207 	dump(title, object, 0);
       
   208     }
       
   209 
       
   210     public static void dump(String title, Object object, int indent) {
       
   211 	dump(title, object, indent, new PrintWriter(System.out, true));
       
   212     }
       
   213 
       
   214     public static void dump(String title, Object object, int indent,
       
   215 	PrintWriter out) {
       
   216 
       
   217 	synchronized (handlers) {
       
   218 	    for (int i = handlers.size() - 1; i >= 0; i--) {
       
   219 		if (handlers.get(i).dump(title, object, indent, out)) {
       
   220 		    return;
       
   221 		}
       
   222 	    }
       
   223 
       
   224 	    out.printf("%sCould not dump %s",
       
   225 		indent(indent), toBaseName(object));
       
   226 	}
       
   227     }
       
   228 
       
   229     public static String indent(int indent) {
       
   230 	char[] chars = new char[indent * _INDENTSIZE];
       
   231 	for (int i = 0; i < chars.length; i++) {
       
   232 	    chars[i] = ' ';
       
   233 	}
       
   234 	return new String(chars);
       
   235     }
       
   236 
       
   237     public static void output(String name, Object o) {
       
   238 	System.out.printf("%s: %s\n", name, toBaseName(o));
       
   239     }
       
   240 
       
   241     public static String toBaseName(Object o) {
       
   242 	if (o == null)
       
   243 	    return null;
       
   244 
       
   245 	Class clazz = o.getClass();
       
   246 	String name = TextUtil.getBaseName(clazz);
       
   247 	if (name.matches(".*\\$\\d+$")) {
       
   248 	    clazz = clazz.getSuperclass();
       
   249 	    name += " (a " + TextUtil.getBaseName(clazz) + ")";
       
   250 	}
       
   251 
       
   252 	return name;
       
   253     }
       
   254 
       
   255     public static void trackComponentFocus() {
       
   256 	KeyboardFocusManager.getCurrentKeyboardFocusManager().
       
   257 	    addPropertyChangeListener("focusOwner",
       
   258 	    new PropertyChangeListener() {
       
   259 		@Override
       
   260 		public void propertyChange(PropertyChangeEvent e) {
       
   261 		    dump(e.getNewValue());
       
   262 		}
       
   263 	    });
       
   264     }
       
   265 
       
   266     public static void trackComponentHierarchy(Component comp) {
       
   267 	addComponentHandler(comp,
       
   268 	    new ComponentHandler() {
       
   269 		@Override
       
   270 		public void handle(Component comp) {
       
   271 		    print(comp);
       
   272 		}
       
   273 
       
   274 		private String print(Component comp) {
       
   275 		    Container parent = comp.getParent();
       
   276 		    String indent = parent == null ? "" : print(parent);
       
   277 		    dump(indent, comp);
       
   278 		    return indent + "  ";
       
   279 		}
       
   280 	    });
       
   281     }
       
   282 }