/**
   * Create a new CachedIntrospectionResults instance for the given class.
   *
   * @param beanClass the bean class to analyze
   * @throws BeansException in case of introspection failure
   */
  private CachedIntrospectionResults(Class beanClass) throws BeansException {
    try {
      if (logger.isTraceEnabled()) {
        logger.trace("Getting BeanInfo for class [" + beanClass.getName() + "]");
      }
      this.beanInfo = Introspector.getBeanInfo(beanClass);

      // Immediately remove class from Introspector cache, to allow for proper
      // garbage collection on class loader shutdown - we cache it here anyway,
      // in a GC-friendly manner. In contrast to CachedIntrospectionResults,
      // Introspector does not use WeakReferences as values of its WeakHashMap!
      Class classToFlush = beanClass;
      do {
        Introspector.flushFromCaches(classToFlush);
        classToFlush = classToFlush.getSuperclass();
      } while (classToFlush != null);

      if (logger.isTraceEnabled()) {
        logger.trace("Caching PropertyDescriptors for class [" + beanClass.getName() + "]");
      }
      this.propertyDescriptorCache = new HashMap();

      // This call is slow so we do it once.
      PropertyDescriptor[] pds = this.beanInfo.getPropertyDescriptors();
      for (int i = 0; i < pds.length; i++) {
        PropertyDescriptor pd = pds[i];
        if (logger.isTraceEnabled()) {
          logger.trace(
              "Found bean property '"
                  + pd.getName()
                  + "'"
                  + (pd.getPropertyType() != null
                      ? " of type [" + pd.getPropertyType().getName() + "]"
                      : "")
                  + (pd.getPropertyEditorClass() != null
                      ? "; editor [" + pd.getPropertyEditorClass().getName() + "]"
                      : ""));
        }
        if (JdkVersion.isAtLeastJava15()) {
          pd =
              new GenericTypeAwarePropertyDescriptor(
                  beanClass,
                  pd.getName(),
                  pd.getReadMethod(),
                  pd.getWriteMethod(),
                  pd.getPropertyEditorClass());
        }
        this.propertyDescriptorCache.put(pd.getName(), pd);
      }
    } catch (IntrospectionException ex) {
      throw new FatalBeanException(
          "Cannot get BeanInfo for object of class [" + beanClass.getName() + "]", ex);
    }
  }
  /**
   * Compares this <code>PropertyDescriptor</code> against the specified object. Returns true if the
   * objects are the same. Two <code>PropertyDescriptor</code>s are the same if the read, write,
   * property types, property editor and flags are equivalent.
   *
   * @since 1.4
   */
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj != null && obj instanceof PropertyDescriptor) {
      PropertyDescriptor other = (PropertyDescriptor) obj;
      Method otherReadMethod = other.getReadMethod();
      Method otherWriteMethod = other.getWriteMethod();

      if (!compareMethods(getReadMethod(), otherReadMethod)) {
        return false;
      }

      if (!compareMethods(getWriteMethod(), otherWriteMethod)) {
        return false;
      }

      if (getPropertyType() == other.getPropertyType()
          && getPropertyEditorClass() == other.getPropertyEditorClass()
          && bound == other.isBound()
          && constrained == other.isConstrained()
          && writeMethodName == other.writeMethodName
          && readMethodName == other.readMethodName) {
        return true;
      }
    }
    return false;
  }
Example #3
0
  /**
   * Get the appropriate editor for the given property.
   *
   * @param prop Property to get editor for.
   * @return Editor to use, or null if none found.
   */
  private PropertyEditor getEditorForProperty(PropertyDescriptor prop) {
    PropertyEditor retval = null;
    Class type = prop.getPropertyEditorClass();
    if (type != null) {
      try {
        retval = (PropertyEditor) type.newInstance();
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    }
    // Handle case where there is no special editor
    // associated with the property. In that case we ask the
    // PropertyEditor manager for the editor registered for the
    // given property type.
    if (retval == null) {
      Class t = prop.getPropertyType();
      if (t != null) {
        retval = PropertyEditorManager.findEditor(t);
      }
    }

    // In the worse case we resort to the generic editor for Object types.
    if (retval == null) {
      retval = PropertyEditorManager.findEditor(Object.class);
    }

    return retval;
  }
Example #4
0
  @SuppressWarnings({"rawtypes"})
  private EditorHelper findHelperFor(PropertyDescriptor prop, Editable subject) {
    EditorHelper res = null;

    // is there an explicit editor specified?
    Class specificEditor = prop.getPropertyEditorClass();

    // did we find one?
    if (specificEditor != null) {
      Object theEditor = null;
      try {
        theEditor = specificEditor.newInstance();
      } catch (Exception e) {
        CorePlugin.logError(Status.ERROR, "whilst finding helper", e);
      }

      if (theEditor instanceof java.beans.PropertyEditor) {
        final java.beans.PropertyEditor propEditor = (java.beans.PropertyEditor) theEditor;
        // ok. wrap it.
        if (!(propEditor instanceof DoNotUseTagEditorInPropertiesView)) {
          if (propEditor.getTags() != null) {
            // ok - do one of the combo-box editor types
            final String[] theTags = propEditor.getTags();
            res = new TagListHelper(theTags, propEditor);
          }
        }
      }
    }

    if (res == null) {

      // ok, find the type of object we're working with
      Class rawClass = EditableWrapper.getPropertyClass(_thisProp);

      for (Iterator iter = _myHelperList.iterator(); iter.hasNext(); ) {
        EditorHelper thisHelper = (EditorHelper) iter.next();
        if (thisHelper.editsThis(rawClass)) {
          res = thisHelper;
          break;
        }
      }

      if (res == null) {
        // ok, log the error
        String msg =
            "editor not found for:"
                + EditableWrapper.getPropertyClass(prop)
                + "("
                + prop.getDisplayName()
                + ")";
        System.out.println(msg);
      }
    }
    return res;
  }
  /**
   * Compare the given {@link PropertyDescriptor} against the given {@link Object} and return {@code
   * true} if they are objects are equivalent, i.e. both are {@code PropertyDescriptor}s whose read
   * method, write method, property types, property editor and flags are equivalent.
   *
   * @see PropertyDescriptor#equals(Object)
   */
  public static boolean equals(PropertyDescriptor pd1, Object obj) {
    if (pd1 == obj) {
      return true;
    }
    if (obj != null && obj instanceof PropertyDescriptor) {
      PropertyDescriptor pd2 = (PropertyDescriptor) obj;
      if (!compareMethods(pd1.getReadMethod(), pd2.getReadMethod())) {
        return false;
      }

      if (!compareMethods(pd1.getWriteMethod(), pd2.getWriteMethod())) {
        return false;
      }

      if (pd1.getPropertyType() == pd2.getPropertyType()
          && pd1.getPropertyEditorClass() == pd2.getPropertyEditorClass()
          && pd1.isBound() == pd2.isBound()
          && pd1.isConstrained() == pd2.isConstrained()) {
        return true;
      }
    }
    return false;
  }
  /*
   * see java.beans.FeatureDescriptor#FeatureDescriptor(FeatureDescriptor)
   */
  public static void copyNonMethodProperties(PropertyDescriptor source, PropertyDescriptor target)
      throws IntrospectionException {

    target.setExpert(source.isExpert());
    target.setHidden(source.isHidden());
    target.setPreferred(source.isPreferred());
    target.setName(source.getName());
    target.setShortDescription(source.getShortDescription());
    target.setDisplayName(source.getDisplayName());

    // copy all attributes (emulating behavior of private FeatureDescriptor#addTable)
    Enumeration<String> keys = source.attributeNames();
    while (keys.hasMoreElements()) {
      String key = keys.nextElement();
      target.setValue(key, source.getValue(key));
    }

    // see java.beans.PropertyDescriptor#PropertyDescriptor(PropertyDescriptor)
    target.setPropertyEditorClass(source.getPropertyEditorClass());
    target.setBound(source.isBound());
    target.setConstrained(source.isConstrained());
  }
Example #7
0
  /**
   * can we edit this property with a drop-down list?
   *
   * @param thisP
   * @return yes/no
   */
  @SuppressWarnings("rawtypes")
  private static boolean supportsListEditor(final PropertyDescriptor thisP) {
    boolean res = false;

    // find out the type of the editor
    final Method m = thisP.getReadMethod();
    final Class cl = m.getReturnType();

    // is there a custom editor for this type?
    final Class c = thisP.getPropertyEditorClass();

    PropertyEditor pe = null;
    // try to create an editor for this class
    try {
      if (c != null) pe = (PropertyEditor) c.newInstance();
    } catch (final Exception e) {
      MWC.Utilities.Errors.Trace.trace(e);
    }

    // did it work?
    if (pe == null) {
      // try to find an editor for this through our manager
      pe = PropertyEditorManager.findEditor(cl);
    }

    // have we managed to create an editor?
    if (pe != null) {
      // retrieve the tags
      final String[] tags = pe.getTags();

      // are there any tags for this class?
      if (tags != null) {
        res = true;
      }
    }

    return res;
  }
  /**
   * Package-private constructor. Merge two property descriptors. Where they conflict, give the
   * second argument (y) priority over the first argument (x).
   *
   * @param x The first (lower priority) PropertyDescriptor
   * @param y The second (higher priority) PropertyDescriptor
   */
  PropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) {
    super(x, y);

    if (y.baseName != null) {
      baseName = y.baseName;
    } else {
      baseName = x.baseName;
    }

    if (y.readMethodName != null) {
      readMethodName = y.readMethodName;
    } else {
      readMethodName = x.readMethodName;
    }

    if (y.writeMethodName != null) {
      writeMethodName = y.writeMethodName;
    } else {
      writeMethodName = x.writeMethodName;
    }

    if (y.propertyTypeRef != null) {
      propertyTypeRef = y.propertyTypeRef;
    } else {
      propertyTypeRef = x.propertyTypeRef;
    }

    // Figure out the merged read method.
    Method xr = x.getReadMethod();
    Method yr = y.getReadMethod();

    // Normally give priority to y's readMethod.
    try {
      if (yr != null && yr.getDeclaringClass() == getClass0()) {
        setReadMethod(yr);
      } else {
        setReadMethod(xr);
      }
    } catch (IntrospectionException ex) {
      // fall through
    }

    // However, if both x and y reference read methods in the same class,
    // give priority to a boolean "is" method over a boolean "get" method.
    if (xr != null
        && yr != null
        && xr.getDeclaringClass() == yr.getDeclaringClass()
        && xr.getReturnType() == boolean.class
        && yr.getReturnType() == boolean.class
        && xr.getName().indexOf("is") == 0
        && yr.getName().indexOf("get") == 0) {
      try {
        setReadMethod(xr);
      } catch (IntrospectionException ex) {
        // fall through
      }
    }

    Method xw = x.getWriteMethod();
    Method yw = y.getWriteMethod();

    try {
      if (yw != null && yw.getDeclaringClass() == getClass0()) {
        setWriteMethod(yw);
      } else {
        setWriteMethod(xw);
      }
    } catch (IntrospectionException ex) {
      // Fall through
    }

    if (y.getPropertyEditorClass() != null) {
      setPropertyEditorClass(y.getPropertyEditorClass());
    } else {
      setPropertyEditorClass(x.getPropertyEditorClass());
    }

    bound = x.bound | y.bound;
    constrained = x.constrained | y.constrained;
  }
Example #9
0
  /**
   * @param prop
   * @param value
   * @return
   */
  public static PropertyEditor findEditor(PropertyDescriptor prop, Object value) {

    PropertyEditor editor = null;
    Class pec = prop.getPropertyEditorClass();
    Class type = prop.getPropertyType();

    try {
      if (pec != null) {
        editor = (PropertyEditor) pec.newInstance();
      }
    } catch (Exception e) {
      editor = null;
    }

    if (editor == null) {
      if (value != null) {
        // Try to unwrap primitives
        if (Primitives.isWrapperType(value.getClass())) {
          editor = PropertyEditorManager.findEditor(Primitives.unwrap(value.getClass()));
        } else {
          editor = PropertyEditorManager.findEditor(value.getClass());
        }
      }
      if (editor == null && (BeanInspector.isJavaPrimitive(value.getClass()))) {
        Class<?> prim = BeanInspector.getBoxedType(value.getClass());
        if (prim != null) {
          editor = PropertyEditorManager.findEditor(prim);
        }
        if (editor == null) {

          prim = BeanInspector.getUnboxedType(value.getClass());
          if (prim != null) {
            editor = PropertyEditorManager.findEditor(prim);
          }
        }
      }

      if (editor == null) {
        editor = PropertyEditorManager.findEditor(type);
      }

      if ((editor == null) && useDefaultGOE) {
        if (type.isArray()) {
          Class<?> unwrapped =
              Primitives.isWrapperType(type.getComponentType())
                  ? Primitives.unwrap(type.getComponentType())
                  : type;
          if (unwrapped.isPrimitive()) {
            editor = new ArrayEditor();
          } else {
            editor = new ObjectArrayEditor<>(unwrapped.getComponentType());
          }
        } else if (type.isEnum()) {
          editor = new EnumEditor();
        } else {
          editor = new GenericObjectEditor();
          ((GenericObjectEditor) editor).setClassType(type);
        }
      }
    }
    if (editor == null) {
      // If it's a user-defined property we give a warning.
      String getterClass = prop.getReadMethod().getDeclaringClass().getName();
      if (getterClass.indexOf("java.") != 0) {
        System.err.println(
            "Warning: Can't find public property editor"
                + " for property \""
                + prop.getDisplayName()
                + "\" (class \""
                + type.getName()
                + "\").  Skipping.");
      }
    } else if (editor instanceof GenericObjectEditor) {
      ((GenericObjectEditor) editor).setClassType(type);
    }
    return editor;
  }
Example #10
0
  @SuppressWarnings("rawtypes")
  private static MenuManager generateListEditorFor(
      final IMenuManager manager,
      final MenuManager subMenu,
      final PropertyDescriptor thisP,
      final Editable[] editables,
      final Layers theLayers,
      final Layer topLevelLayer) {

    // find out the type of the editor
    final Method m = thisP.getReadMethod();
    final Class cl = m.getReturnType();
    MenuManager result = subMenu;

    // is there a custom editor for this type?
    final Class c = thisP.getPropertyEditorClass();

    PropertyEditor pe = null;
    // try to create an editor for this class
    try {
      if (c != null) pe = (PropertyEditor) c.newInstance();
    } catch (final Exception e) {
      MWC.Utilities.Errors.Trace.trace(e);
    }

    // did it work?
    if (pe == null) {
      // try to find an editor for this through our manager
      pe = PropertyEditorManager.findEditor(cl);
    }

    // retrieve the tags
    final String[] tags = pe.getTags();

    // are there any tags for this class?
    if (tags != null) {
      // create a drop-down list
      final MenuManager thisChoice = new MenuManager(thisP.getDisplayName());

      // sort out the setter details
      final Method getter = thisP.getReadMethod();

      // get the current value
      Object val = null;
      try {
        val = getter.invoke(editables[0], (Object[]) null);
      } catch (final Exception e) {
        MWC.Utilities.Errors.Trace.trace(e);
      }
      pe.setValue(val);

      // convert the current value to text
      final String currentValue = pe.getAsText();

      // and now a drop-down item for each options
      for (int j = 0; j < tags.length; j++) {
        final String thisTag = tags[j];
        pe.setAsText(thisTag);
        final Object thisValue = pe.getValue();

        // create the item
        final IAction thisA =
            new Action(thisTag, IAction.AS_RADIO_BUTTON) {
              public void run() {
                try {
                  // hey, since this is a radio button, we get two events when the
                  // selection changes - one for the value being unset, and the
                  // other
                  // for the value being set. So just fire for the new value (the
                  // one that's checked)
                  if (isChecked()) {
                    final Method setter = thisP.getWriteMethod();

                    // ok, place the change in the action
                    final ListPropertyAction la =
                        new ListPropertyAction(
                            thisP.getDisplayName(),
                            editables,
                            getter,
                            setter,
                            thisValue,
                            theLayers,
                            topLevelLayer);

                    // and add it to the history
                    CorePlugin.run(la);
                  }
                } catch (final Exception e) {
                  CorePlugin.logError(
                      IStatus.INFO, "While executing select editor for:" + thisP, e);
                }
              }
            };

        // is this the current one?
        if (thisTag.equals(currentValue)) {
          thisA.setChecked(true);
        }

        // add it to the menu
        thisChoice.add(thisA);
      }

      // is our sub-menu already created?
      if (result == null) {
        String nameStr;
        if (editables.length > 1) nameStr = MULTIPLE_ITEMS_STR;
        else nameStr = editables[0].getName();

        result = new MenuManager(nameStr);
        manager.add(result);
      }

      result.add(thisChoice);
    }

    return result;
  }
Example #11
0
 /*
  * Attempt to find custom property editor on descriptor first, else try the propery editor manager.
  */
 protected PropertyEditor getPropertyEditor(PropertyDescriptor desc)
     throws InstantiationException, IllegalAccessException {
   Class<?> cls = desc.getPropertyEditorClass();
   if (null != cls) return (PropertyEditor) cls.newInstance();
   return getPropertyEditorValue(desc.getPropertyType());
 }