Example #1
0
 static {
   // compute primitives/primitiveMap/primitiveToWrapper
   for (Class<?> c : primitiveWrappers) {
     try {
       Field f = c.getField("TYPE");
       Class<?> p = (Class<?>) f.get(null);
       primitives.add(p);
       primitiveMap.put(p.getName(), p);
       primitiveToWrapper.put(p.getName(), c);
     } catch (Exception e) {
       throw new AssertionError(e);
     }
   }
   // compute editableTypes
   for (Class<?> c : primitives) {
     editableTypes.add(c.getName());
   }
   for (Class<?> c : primitiveWrappers) {
     editableTypes.add(c.getName());
   }
   for (Class<?> c : extraEditableClasses) {
     editableTypes.add(c.getName());
   }
   // compute numericalTypes
   for (Class<?> c : primitives) {
     String name = c.getName();
     if (!name.equals(Boolean.TYPE.getName())) {
       numericalTypes.add(name);
     }
   }
   for (Class<?> c : primitiveWrappers) {
     String name = c.getName();
     if (!name.equals(Boolean.class.getName())) {
       numericalTypes.add(name);
     }
   }
 }
Example #2
0
public class Utils {

  private Utils() {}

  private static Set<Integer> tableNavigationKeys =
      new HashSet<Integer>(
          Arrays.asList(
              new Integer[] {
                KeyEvent.VK_TAB, KeyEvent.VK_ENTER,
                KeyEvent.VK_HOME, KeyEvent.VK_END,
                KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT,
                KeyEvent.VK_UP, KeyEvent.VK_DOWN,
                KeyEvent.VK_PAGE_UP, KeyEvent.VK_PAGE_DOWN
              }));

  private static final Set<Class<?>> primitiveWrappers =
      new HashSet<Class<?>>(
          Arrays.asList(
              new Class<?>[] {
                Byte.class, Short.class, Integer.class, Long.class,
                Float.class, Double.class, Character.class, Boolean.class
              }));

  private static final Set<Class<?>> primitives = new HashSet<Class<?>>();

  private static final Map<String, Class<?>> primitiveMap = new HashMap<String, Class<?>>();

  private static final Map<String, Class<?>> primitiveToWrapper = new HashMap<String, Class<?>>();

  private static final Set<String> editableTypes = new HashSet<String>();

  private static final Set<Class<?>> extraEditableClasses =
      new HashSet<Class<?>>(
          Arrays.asList(
              new Class<?>[] {
                BigDecimal.class, BigInteger.class, Number.class, String.class, ObjectName.class
              }));

  private static final Set<String> numericalTypes = new HashSet<String>();

  private static final Set<String> extraNumericalTypes =
      new HashSet<String>(
          Arrays.asList(
              new String[] {
                BigDecimal.class.getName(), BigInteger.class.getName(), Number.class.getName()
              }));

  private static final Set<String> booleanTypes =
      new HashSet<String>(
          Arrays.asList(new String[] {Boolean.TYPE.getName(), Boolean.class.getName()}));

  static {
    // compute primitives/primitiveMap/primitiveToWrapper
    for (Class<?> c : primitiveWrappers) {
      try {
        Field f = c.getField("TYPE");
        Class<?> p = (Class<?>) f.get(null);
        primitives.add(p);
        primitiveMap.put(p.getName(), p);
        primitiveToWrapper.put(p.getName(), c);
      } catch (Exception e) {
        throw new AssertionError(e);
      }
    }
    // compute editableTypes
    for (Class<?> c : primitives) {
      editableTypes.add(c.getName());
    }
    for (Class<?> c : primitiveWrappers) {
      editableTypes.add(c.getName());
    }
    for (Class<?> c : extraEditableClasses) {
      editableTypes.add(c.getName());
    }
    // compute numericalTypes
    for (Class<?> c : primitives) {
      String name = c.getName();
      if (!name.equals(Boolean.TYPE.getName())) {
        numericalTypes.add(name);
      }
    }
    for (Class<?> c : primitiveWrappers) {
      String name = c.getName();
      if (!name.equals(Boolean.class.getName())) {
        numericalTypes.add(name);
      }
    }
  }

  /**
   * This method returns the class matching the name className. It's used to cater for the primitive
   * types.
   */
  public static Class<?> getClass(String className) throws ClassNotFoundException {
    Class<?> c;
    if ((c = primitiveMap.get(className)) != null) return c;
    return Class.forName(className);
  }

  /** Check if the given collection is a uniform collection of the given type. */
  public static boolean isUniformCollection(Collection<?> c, Class<?> e) {
    if (e == null) {
      throw new IllegalArgumentException("Null reference type");
    }
    if (c == null) {
      throw new IllegalArgumentException("Null collection");
    }
    if (c.isEmpty()) {
      return false;
    }
    for (Object o : c) {
      if (o == null || !e.isAssignableFrom(o.getClass())) {
        return false;
      }
    }
    return true;
  }

  /**
   * Check if the given element denotes a supported array-friendly data structure, i.e. a data
   * structure jconsole can render as an array.
   */
  public static boolean canBeRenderedAsArray(Object elem) {
    if (isSupportedArray(elem)) return true;
    if (elem instanceof Collection) {
      Collection<?> c = (Collection<?>) elem;
      if (c.isEmpty()) {
        // Empty collections of any Java type are not handled as arrays
        //
        return false;
      } else {
        // - Collections of CompositeData/TabularData are not handled
        //   as arrays
        // - Collections of other Java types are handled as arrays
        //
        return !isUniformCollection(c, CompositeData.class)
            && !isUniformCollection(c, TabularData.class);
      }
    }
    if (elem instanceof Map) {
      return !(elem instanceof TabularData);
    }
    return false;
  }

  /**
   * Check if the given element is an array.
   *
   * <p>Multidimensional arrays are not supported.
   *
   * <p>Non-empty 1-dimensional arrays of CompositeData and TabularData are not handled as arrays
   * but as tabular data.
   */
  public static boolean isSupportedArray(Object elem) {
    if (elem == null || !elem.getClass().isArray()) {
      return false;
    }
    Class<?> ct = elem.getClass().getComponentType();
    if (ct.isArray()) {
      return false;
    }
    if (Array.getLength(elem) > 0
        && (CompositeData.class.isAssignableFrom(ct) || TabularData.class.isAssignableFrom(ct))) {
      return false;
    }
    return true;
  }

  /**
   * This method provides a readable classname if it's an array, i.e. either the classname of the
   * component type for arrays of java reference types or the name of the primitive type for arrays
   * of java primitive types. Otherwise, it returns null.
   */
  public static String getArrayClassName(String name) {
    String className = null;
    if (name.startsWith("[")) {
      int index = name.lastIndexOf("[");
      className = name.substring(index, name.length());
      if (className.startsWith("[L")) {
        className = className.substring(2, className.length() - 1);
      } else {
        try {
          Class<?> c = Class.forName(className);
          className = c.getComponentType().getName();
        } catch (ClassNotFoundException e) {
          // Should not happen
          throw new IllegalArgumentException("Bad class name " + name, e);
        }
      }
    }
    return className;
  }

  /**
   * This methods provides a readable classname. If the supplied name parameter denotes an array
   * this method returns either the classname of the component type for arrays of java reference
   * types or the name of the primitive type for arrays of java primitive types followed by n-times
   * "[]" where 'n' denotes the arity of the array. Otherwise, if the supplied name doesn't denote
   * an array it returns the same classname.
   */
  public static String getReadableClassName(String name) {
    String className = getArrayClassName(name);
    if (className == null) return name;
    int index = name.lastIndexOf("[");
    StringBuilder brackets = new StringBuilder(className);
    for (int i = 0; i <= index; i++) {
      brackets.append("[]");
    }
    return brackets.toString();
  }

  /** This method tells whether the type is editable (means can be created with a String or not) */
  public static boolean isEditableType(String type) {
    return editableTypes.contains(type);
  }

  /**
   * This method inserts a default value for the standard java types, else it inserts the text name
   * of the expected class type. It acts to give a clue as to the input type.
   */
  public static String getDefaultValue(String type) {
    if (numericalTypes.contains(type) || extraNumericalTypes.contains(type)) {
      return "0";
    }
    if (booleanTypes.contains(type)) {
      return "true";
    }
    type = getReadableClassName(type);
    int i = type.lastIndexOf('.');
    if (i > 0) {
      return type.substring(i + 1, type.length());
    } else {
      return type;
    }
  }

  /** Try to create a Java object using a one-string-param constructor. */
  public static Object newStringConstructor(String type, String param) throws Exception {
    Constructor c = Utils.getClass(type).getConstructor(String.class);
    try {
      return c.newInstance(param);
    } catch (InvocationTargetException e) {
      Throwable t = e.getTargetException();
      if (t instanceof Exception) {
        throw (Exception) t;
      } else {
        throw e;
      }
    }
  }

  /** Try to convert a string value into a numerical value. */
  private static Number createNumberFromStringValue(String value) throws NumberFormatException {
    final String suffix = value.substring(value.length() - 1);
    if ("L".equalsIgnoreCase(suffix)) {
      return Long.valueOf(value.substring(0, value.length() - 1));
    }
    if ("F".equalsIgnoreCase(suffix)) {
      return Float.valueOf(value.substring(0, value.length() - 1));
    }
    if ("D".equalsIgnoreCase(suffix)) {
      return Double.valueOf(value.substring(0, value.length() - 1));
    }
    try {
      return Integer.valueOf(value);
    } catch (NumberFormatException e) {
      // OK: Ignore exception...
    }
    try {
      return Long.valueOf(value);
    } catch (NumberFormatException e1) {
      // OK: Ignore exception...
    }
    try {
      return Double.valueOf(value);
    } catch (NumberFormatException e2) {
      // OK: Ignore exception...
    }
    throw new NumberFormatException(
        "Cannot convert string value '" + value + "' into a numerical value");
  }

  /**
   * This method attempts to create an object of the given "type" using the "value" parameter. e.g.
   * calling createObjectFromString("java.lang.Integer", "10") will return an Integer object
   * initialized to 10.
   */
  public static Object createObjectFromString(String type, String value) throws Exception {
    Object result;
    if (primitiveToWrapper.containsKey(type)) {
      if (type.equals(Character.TYPE.getName())) {
        result = new Character(value.charAt(0));
      } else {
        result = newStringConstructor(((Class<?>) primitiveToWrapper.get(type)).getName(), value);
      }
    } else if (type.equals(Character.class.getName())) {
      result = new Character(value.charAt(0));
    } else if (Number.class.isAssignableFrom(Utils.getClass(type))) {
      result = createNumberFromStringValue(value);
    } else if (value == null || value.toString().equals("null")) {
      // hack for null value
      result = null;
    } else {
      // try to create a Java object using
      // the one-string-param constructor
      result = newStringConstructor(type, value);
    }
    return result;
  }

  /**
   * This method is responsible for converting the inputs given by the user into a useful object
   * array for passing into a parameter array.
   */
  public static Object[] getParameters(XTextField[] inputs, String[] params) throws Exception {
    Object result[] = new Object[inputs.length];
    Object userInput;
    for (int i = 0; i < inputs.length; i++) {
      userInput = inputs[i].getValue();
      // if it's already a complex object, use the value
      // else try to instantiate with string constructor
      if (userInput instanceof XObject) {
        result[i] = ((XObject) userInput).getObject();
      } else {
        result[i] = createObjectFromString(params[i].toString(), (String) userInput);
      }
    }
    return result;
  }

  /** If the exception is wrapped, unwrap it. */
  public static Throwable getActualException(Throwable e) {
    if (e instanceof ExecutionException) e = e.getCause();
    if (e instanceof MBeanException
        || e instanceof RuntimeMBeanException
        || e instanceof RuntimeOperationsException
        || e instanceof ReflectionException) {
      Throwable t = e.getCause();
      if (t != null) return t;
    }
    return e;
  }

  @SuppressWarnings("serial")
  public static class ReadOnlyTableCellEditor extends DefaultCellEditor {
    public ReadOnlyTableCellEditor(JTextField tf) {
      super(tf);
      tf.addFocusListener(new EditFocusAdapter(this));
      tf.addKeyListener(new CopyKeyAdapter());
    }
  }

  public static class EditFocusAdapter extends FocusAdapter {
    private CellEditor editor;

    public EditFocusAdapter(CellEditor editor) {
      this.editor = editor;
    }

    @Override
    public void focusLost(FocusEvent e) {
      editor.stopCellEditing();
    }
  };

  public static class CopyKeyAdapter extends KeyAdapter {
    private static final String defaultEditorKitCopyActionName = DefaultEditorKit.copyAction;
    private static final String transferHandlerCopyActionName =
        (String) TransferHandler.getCopyAction().getValue(Action.NAME);

    @Override
    public void keyPressed(KeyEvent e) {
      // Accept "copy" key strokes
      KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
      JComponent comp = (JComponent) e.getSource();
      for (int i = 0; i < 3; i++) {
        InputMap im = comp.getInputMap(i);
        Object key = im.get(ks);
        if (defaultEditorKitCopyActionName.equals(key)
            || transferHandlerCopyActionName.equals(key)) {
          return;
        }
      }
      // Accept JTable navigation key strokes
      if (!tableNavigationKeys.contains(e.getKeyCode())) {
        e.consume();
      }
    }

    @Override
    public void keyTyped(KeyEvent e) {
      e.consume();
    }
  }
}