jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java
changeset 55 5ecee29e98d8
parent 2 90ce3da70b43
child 715 f16baef3a20e
equal deleted inserted replaced
54:a007508f7193 55:5ecee29e98d8
     1 /*
     1 /*
     2  * Copyright 2004-2006 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 2004-2007 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     7  * published by the Free Software Foundation.  Sun designates this
    27 
    27 
    28 import java.awt.event.*;
    28 import java.awt.event.*;
    29 import java.lang.reflect.*;
    29 import java.lang.reflect.*;
    30 import java.math.BigDecimal;
    30 import java.math.BigDecimal;
    31 import java.math.BigInteger;
    31 import java.math.BigInteger;
       
    32 import java.util.*;
       
    33 import java.util.concurrent.ExecutionException;
    32 import javax.management.*;
    34 import javax.management.*;
    33 import javax.management.openmbean.*;
    35 import javax.management.openmbean.*;
    34 import javax.swing.*;
    36 import javax.swing.*;
    35 import javax.swing.text.*;
    37 import javax.swing.text.*;
    36 import java.util.*;
       
    37 
    38 
    38 public class Utils {
    39 public class Utils {
    39 
    40 
    40     private Utils() {
    41     private Utils() {
    41     }
    42     }
    42 
       
    43     private static Set<Integer> tableNavigationKeys =
    43     private static Set<Integer> tableNavigationKeys =
    44             new HashSet<Integer>(Arrays.asList(new Integer[] {
    44             new HashSet<Integer>(Arrays.asList(new Integer[]{
    45         KeyEvent.VK_TAB, KeyEvent.VK_ENTER,
    45         KeyEvent.VK_TAB, KeyEvent.VK_ENTER,
    46         KeyEvent.VK_HOME, KeyEvent.VK_END,
    46         KeyEvent.VK_HOME, KeyEvent.VK_END,
    47         KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
    47         KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
    48         KeyEvent.VK_UP, KeyEvent.VK_DOWN,
    48         KeyEvent.VK_UP, KeyEvent.VK_DOWN,
    49         KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN}));
    49         KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN
    50 
    50     }));
    51     private static final Set<Class<?>> primitiveWrappers =
    51     private static final Set<Class<?>> primitiveWrappers =
    52             new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {
    52             new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
    53         Byte.class, Short.class, Integer.class, Long.class,
    53         Byte.class, Short.class, Integer.class, Long.class,
    54         Float.class, Double.class, Character.class, Boolean.class}));
    54         Float.class, Double.class, Character.class, Boolean.class
    55 
    55     }));
    56     private static final Set<Class<?>> primitives = new HashSet<Class<?>>();
    56     private static final Set<Class<?>> primitives = new HashSet<Class<?>>();
    57 
       
    58     private static final Map<String, Class<?>> primitiveMap =
    57     private static final Map<String, Class<?>> primitiveMap =
    59             new HashMap<String, Class<?>>();
    58             new HashMap<String, Class<?>>();
    60 
       
    61     private static final Map<String, Class<?>> primitiveToWrapper =
    59     private static final Map<String, Class<?>> primitiveToWrapper =
    62             new HashMap<String, Class<?>>();
    60             new HashMap<String, Class<?>>();
    63 
       
    64     private static final Set<String> editableTypes = new HashSet<String>();
    61     private static final Set<String> editableTypes = new HashSet<String>();
    65 
       
    66     private static final Set<Class<?>> extraEditableClasses =
    62     private static final Set<Class<?>> extraEditableClasses =
    67             new HashSet<Class<?>>(Arrays.asList(new Class<?>[] {
    63             new HashSet<Class<?>>(Arrays.asList(new Class<?>[]{
    68         BigDecimal.class, BigInteger.class, Number.class,
    64         BigDecimal.class, BigInteger.class, Number.class,
    69         String.class, ObjectName.class}));
    65         String.class, ObjectName.class
    70 
    66     }));
    71     private static final Set<String> numericalTypes = new HashSet<String>();
    67     private static final Set<String> numericalTypes = new HashSet<String>();
    72 
       
    73     private static final Set<String> extraNumericalTypes =
    68     private static final Set<String> extraNumericalTypes =
    74             new HashSet<String>(Arrays.asList(new String[] {
    69             new HashSet<String>(Arrays.asList(new String[]{
    75         BigDecimal.class.getName(), BigInteger.class.getName(),
    70         BigDecimal.class.getName(), BigInteger.class.getName(),
    76         Number.class.getName()}));
    71         Number.class.getName()
    77 
    72     }));
    78     private static final Set<String> booleanTypes =
    73     private static final Set<String> booleanTypes =
    79             new HashSet<String>(Arrays.asList(new String[] {
    74             new HashSet<String>(Arrays.asList(new String[]{
    80         Boolean.TYPE.getName(), Boolean.class.getName()}));
    75         Boolean.TYPE.getName(), Boolean.class.getName()
       
    76     }));
    81 
    77 
    82     static {
    78     static {
    83         // compute primitives/primitiveMap/primitiveToWrapper
    79         // compute primitives/primitiveMap/primitiveToWrapper
    84         for (Class<?> c : primitiveWrappers) {
    80         for (Class<?> c : primitiveWrappers) {
    85             try {
    81             try {
   120     /**
   116     /**
   121      * This method returns the class matching the name className.
   117      * This method returns the class matching the name className.
   122      * It's used to cater for the primitive types.
   118      * It's used to cater for the primitive types.
   123      */
   119      */
   124     public static Class<?> getClass(String className)
   120     public static Class<?> getClass(String className)
   125     throws ClassNotFoundException {
   121             throws ClassNotFoundException {
   126         Class<?> c;
   122         Class<?> c;
   127         if ((c = primitiveMap.get(className)) != null)
   123         if ((c = primitiveMap.get(className)) != null) {
   128             return c;
   124             return c;
       
   125         }
   129         return Class.forName(className);
   126         return Class.forName(className);
   130     }
   127     }
   131 
   128 
   132     /**
   129     /**
   133      * Check if the given collection is a uniform collection of the given type.
   130      * Check if the given collection is a uniform collection of the given type.
   153     /**
   150     /**
   154      * Check if the given element denotes a supported array-friendly data
   151      * Check if the given element denotes a supported array-friendly data
   155      * structure, i.e. a data structure jconsole can render as an array.
   152      * structure, i.e. a data structure jconsole can render as an array.
   156      */
   153      */
   157     public static boolean canBeRenderedAsArray(Object elem) {
   154     public static boolean canBeRenderedAsArray(Object elem) {
   158         if (isSupportedArray(elem)) return true;
   155         if (isSupportedArray(elem)) {
       
   156             return true;
       
   157         }
   159         if (elem instanceof Collection) {
   158         if (elem instanceof Collection) {
   160             Collection<?> c = (Collection<?>) elem;
   159             Collection<?> c = (Collection<?>) elem;
   161             if (c.isEmpty()) {
   160             if (c.isEmpty()) {
   162                 // Empty collections of any Java type are not handled as arrays
   161                 // Empty collections of any Java type are not handled as arrays
   163                 //
   162                 //
   166                 // - Collections of CompositeData/TabularData are not handled
   165                 // - Collections of CompositeData/TabularData are not handled
   167                 //   as arrays
   166                 //   as arrays
   168                 // - Collections of other Java types are handled as arrays
   167                 // - Collections of other Java types are handled as arrays
   169                 //
   168                 //
   170                 return !isUniformCollection(c, CompositeData.class) &&
   169                 return !isUniformCollection(c, CompositeData.class) &&
   171                        !isUniformCollection(c, TabularData.class);
   170                         !isUniformCollection(c, TabularData.class);
   172             }
   171             }
   173         }
   172         }
   174         if (elem instanceof Map) {
   173         if (elem instanceof Map) {
   175             return !(elem instanceof TabularData);
   174             return !(elem instanceof TabularData);
   176         }
   175         }
   237      * n-times "[]" where 'n' denotes the arity of the array. Otherwise, if
   236      * n-times "[]" where 'n' denotes the arity of the array. Otherwise, if
   238      * the supplied name doesn't denote an array it returns the same classname.
   237      * the supplied name doesn't denote an array it returns the same classname.
   239      */
   238      */
   240     public static String getReadableClassName(String name) {
   239     public static String getReadableClassName(String name) {
   241         String className = getArrayClassName(name);
   240         String className = getArrayClassName(name);
   242         if (className == null) return name;
   241         if (className == null) {
       
   242             return name;
       
   243         }
   243         int index = name.lastIndexOf("[");
   244         int index = name.lastIndexOf("[");
   244         StringBuilder brackets = new StringBuilder(className);
   245         StringBuilder brackets = new StringBuilder(className);
   245         for (int i = 0; i <= index; i++) {
   246         for (int i = 0; i <= index; i++) {
   246             brackets.append("[]");
   247             brackets.append("[]");
   247         }
   248         }
   280 
   281 
   281     /**
   282     /**
   282      * Try to create a Java object using a one-string-param constructor.
   283      * Try to create a Java object using a one-string-param constructor.
   283      */
   284      */
   284     public static Object newStringConstructor(String type, String param)
   285     public static Object newStringConstructor(String type, String param)
   285     throws Exception {
   286             throws Exception {
   286         Constructor c = Utils.getClass(type).getConstructor(String.class);
   287         Constructor c = Utils.getClass(type).getConstructor(String.class);
   287         try {
   288         try {
   288             return c.newInstance(param);
   289             return c.newInstance(param);
   289         } catch (InvocationTargetException e) {
   290         } catch (InvocationTargetException e) {
   290             Throwable t = e.getTargetException();
   291             Throwable t = e.getTargetException();
   298 
   299 
   299     /**
   300     /**
   300      * Try to convert a string value into a numerical value.
   301      * Try to convert a string value into a numerical value.
   301      */
   302      */
   302     private static Number createNumberFromStringValue(String value)
   303     private static Number createNumberFromStringValue(String value)
   303     throws NumberFormatException {
   304             throws NumberFormatException {
   304         final String suffix = value.substring(value.length() - 1);
   305         final String suffix = value.substring(value.length() - 1);
   305         if ("L".equalsIgnoreCase(suffix)) {
   306         if ("L".equalsIgnoreCase(suffix)) {
   306             return Long.valueOf(value.substring(0, value.length() - 1));
   307             return Long.valueOf(value.substring(0, value.length() - 1));
   307         }
   308         }
   308         if ("F".equalsIgnoreCase(suffix)) {
   309         if ("F".equalsIgnoreCase(suffix)) {
   312             return Double.valueOf(value.substring(0, value.length() - 1));
   313             return Double.valueOf(value.substring(0, value.length() - 1));
   313         }
   314         }
   314         try {
   315         try {
   315             return Integer.valueOf(value);
   316             return Integer.valueOf(value);
   316         } catch (NumberFormatException e) {
   317         } catch (NumberFormatException e) {
   317             // OK: Ignore exception...
   318         // OK: Ignore exception...
   318         }
   319         }
   319         try {
   320         try {
   320             return Long.valueOf(value);
   321             return Long.valueOf(value);
   321         } catch (NumberFormatException e1) {
   322         } catch (NumberFormatException e1) {
   322             // OK: Ignore exception...
   323         // OK: Ignore exception...
   323         }
   324         }
   324         try {
   325         try {
   325             return Double.valueOf(value);
   326             return Double.valueOf(value);
   326         } catch (NumberFormatException e2) {
   327         } catch (NumberFormatException e2) {
   327             // OK: Ignore exception...
   328         // OK: Ignore exception...
   328         }
   329         }
   329         throw new NumberFormatException("Cannot convert string value '" +
   330         throw new NumberFormatException("Cannot convert string value '" +
   330                 value + "' into a numerical value");
   331                 value + "' into a numerical value");
   331     }
   332     }
   332 
   333 
   335      * using the "value" parameter.
   336      * using the "value" parameter.
   336      * e.g. calling createObjectFromString("java.lang.Integer", "10")
   337      * e.g. calling createObjectFromString("java.lang.Integer", "10")
   337      * will return an Integer object initialized to 10.
   338      * will return an Integer object initialized to 10.
   338      */
   339      */
   339     public static Object createObjectFromString(String type, String value)
   340     public static Object createObjectFromString(String type, String value)
   340     throws Exception {
   341             throws Exception {
   341         Object result;
   342         Object result;
   342         if (primitiveToWrapper.containsKey(type)) {
   343         if (primitiveToWrapper.containsKey(type)) {
   343             if (type.equals(Character.TYPE.getName())) {
   344             if (type.equals(Character.TYPE.getName())) {
   344                 result = new Character(value.charAt(0));
   345                 result = new Character(value.charAt(0));
   345             } else {
   346             } else {
   365     /**
   366     /**
   366      * This method is responsible for converting the inputs given by the user
   367      * This method is responsible for converting the inputs given by the user
   367      * into a useful object array for passing into a parameter array.
   368      * into a useful object array for passing into a parameter array.
   368      */
   369      */
   369     public static Object[] getParameters(XTextField[] inputs, String[] params)
   370     public static Object[] getParameters(XTextField[] inputs, String[] params)
   370     throws Exception {
   371             throws Exception {
   371         Object result[] = new Object[inputs.length];
   372         Object result[] = new Object[inputs.length];
   372         Object userInput;
   373         Object userInput;
   373         for (int i = 0; i < inputs.length; i++) {
   374         for (int i = 0; i < inputs.length; i++) {
   374             userInput = inputs[i].getValue();
   375             userInput = inputs[i].getValue();
   375             // if it's already a complex object, use the value
   376             // if it's already a complex object, use the value
   386 
   387 
   387     /**
   388     /**
   388      * If the exception is wrapped, unwrap it.
   389      * If the exception is wrapped, unwrap it.
   389      */
   390      */
   390     public static Throwable getActualException(Throwable e) {
   391     public static Throwable getActualException(Throwable e) {
       
   392         if (e instanceof ExecutionException) {
       
   393             e = e.getCause();
       
   394         }
   391         if (e instanceof MBeanException ||
   395         if (e instanceof MBeanException ||
   392                 e instanceof RuntimeMBeanException ||
   396                 e instanceof RuntimeMBeanException ||
   393                 e instanceof RuntimeOperationsException ||
   397                 e instanceof RuntimeOperationsException ||
   394                 e instanceof ReflectionException) {
   398                 e instanceof ReflectionException) {
   395             Throwable t = e.getCause();
   399             Throwable t = e.getCause();
   396             if (t != null) return t;
   400             if (t != null) {
       
   401                 return t;
       
   402             }
   397         }
   403         }
   398         return e;
   404         return e;
   399     }
   405     }
   400 
   406 
   401     @SuppressWarnings("serial")
   407     @SuppressWarnings("serial")
   402     public static class ReadOnlyTableCellEditor
   408     public static class ReadOnlyTableCellEditor
   403             extends DefaultCellEditor {
   409             extends DefaultCellEditor {
       
   410 
   404         public ReadOnlyTableCellEditor(JTextField tf) {
   411         public ReadOnlyTableCellEditor(JTextField tf) {
   405             super(tf);
   412             super(tf);
   406             tf.addFocusListener(new Utils.EditFocusAdapter(this));
   413             tf.addFocusListener(new Utils.EditFocusAdapter(this));
   407             tf.addKeyListener(new Utils.CopyKeyAdapter());
   414             tf.addKeyListener(new Utils.CopyKeyAdapter());
   408         }
   415         }
   409     }
   416     }
   410 
   417 
   411     public static class EditFocusAdapter extends FocusAdapter {
   418     public static class EditFocusAdapter extends FocusAdapter {
       
   419 
   412         private CellEditor editor;
   420         private CellEditor editor;
       
   421 
   413         public EditFocusAdapter(CellEditor editor) {
   422         public EditFocusAdapter(CellEditor editor) {
   414             this.editor = editor;
   423             this.editor = editor;
   415         }
   424         }
       
   425 
       
   426         @Override
   416         public void focusLost(FocusEvent e) {
   427         public void focusLost(FocusEvent e) {
   417             editor.stopCellEditing();
   428             editor.stopCellEditing();
   418         }
   429         }
   419     };
   430     }
   420 
   431 
   421     public static class CopyKeyAdapter extends KeyAdapter {
   432     public static class CopyKeyAdapter extends KeyAdapter {
   422         private static final String defaultEditorKitCopyActionName =
   433         private static final String defaultEditorKitCopyActionName =
   423                 DefaultEditorKit.copyAction;
   434                 DefaultEditorKit.copyAction;
   424         private static final String transferHandlerCopyActionName =
   435         private static final String transferHandlerCopyActionName =
   425                 (String) TransferHandler.getCopyAction().getValue(Action.NAME);
   436                 (String) TransferHandler.getCopyAction().getValue(Action.NAME);
       
   437         @Override
   426         public void keyPressed(KeyEvent e) {
   438         public void keyPressed(KeyEvent e) {
   427             // Accept "copy" key strokes
   439             // Accept "copy" key strokes
   428             KeyStroke ks = KeyStroke.getKeyStroke(
   440             KeyStroke ks = KeyStroke.getKeyStroke(
   429                     e.getKeyCode(), e.getModifiers());
   441                     e.getKeyCode(), e.getModifiers());
   430             JComponent comp = (JComponent) e.getSource();
   442             JComponent comp = (JComponent) e.getSource();
   439             // Accept JTable navigation key strokes
   451             // Accept JTable navigation key strokes
   440             if (!tableNavigationKeys.contains(e.getKeyCode())) {
   452             if (!tableNavigationKeys.contains(e.getKeyCode())) {
   441                 e.consume();
   453                 e.consume();
   442             }
   454             }
   443         }
   455         }
       
   456 
       
   457         @Override
   444         public void keyTyped(KeyEvent e) {
   458         public void keyTyped(KeyEvent e) {
   445             e.consume();
   459             e.consume();
   446         }
   460         }
   447     }
   461     }
   448 }
   462 }