public ObjectPropertyDescriptor(
      DBPPropertySource source,
      ObjectPropertyGroupDescriptor parent,
      Property propInfo,
      Method getter) {
    super(source, parent, getter, propInfo.id(), propInfo.order());
    this.propInfo = propInfo;

    final String propertyName = BeanUtils.getPropertyNameFromGetter(getter.getName());
    declaringClass = getter.getDeclaringClass();
    Class<?> c = declaringClass;
    while (setter == null && c != Object.class && c != null) {
      this.setter = BeanUtils.getSetMethod(c, propertyName);
      if (setter == null) {
        c = c.getSuperclass();
      }
    }

    // Obtain value transformer
    Class<? extends IPropertyValueTransformer> valueTransformerClass = propInfo.valueTransformer();
    if (valueTransformerClass != null && valueTransformerClass != IPropertyValueTransformer.class) {
      try {
        valueTransformer = valueTransformerClass.newInstance();
      } catch (Throwable e) {
        log.warn("Can't create value transformer", e);
      }
    }

    this.propName =
        propInfo.hidden()
            ? getId()
            : getLocalizedString(propInfo.name(), Property.RESOURCE_TYPE_NAME, getId());
    this.propDescription =
        CommonUtils.isEmpty(propInfo.description())
            ? propName
            : getLocalizedString(propInfo.name(), Property.RESOURCE_TYPE_DESCRIPTION, propName);
  }