Example usage for java.beans BeanInfo getPropertyDescriptors

List of usage examples for java.beans BeanInfo getPropertyDescriptors

Introduction

In this page you can find the example usage for java.beans BeanInfo getPropertyDescriptors.

Prototype

PropertyDescriptor[] getPropertyDescriptors();

Source Link

Document

Returns descriptors for all properties of the bean.

Usage

From source file:org.hawkular.inventory.impl.tinkerpop.sql.impl.SqlGraph.java

private void setupDataSource(DataSource dataSource, Configuration configuration) throws Exception {
    BeanInfo beanInfo = Introspector.getBeanInfo(dataSource.getClass());
    PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
    Map<String, PropertyDescriptor> propsByName = new HashMap<>();
    for (PropertyDescriptor p : properties) {
        propsByName.put(p.getName().toLowerCase(), p);
    }//from w  ww. ja v a2  s .c o  m

    Iterator it = configuration.getKeys("sql.datasource");
    while (it.hasNext()) {
        String key = (String) it.next();
        String property = key.substring("sql.datasource.".length()).toLowerCase();

        PropertyDescriptor d = propsByName.get(property);

        if (d == null) {
            continue;
        }

        Method write = d.getWriteMethod();
        if (write != null) {
            write.invoke(dataSource, configuration.getProperty(key));
        }
    }
}

From source file:org.lnicholls.galleon.gui.HMEConfigurationPanel.java

public HMEConfigurationPanel(Object bean) {

    setLayout(new GridLayout(0, 1));

    target = bean;/*from  w w  w . j a  v a  2 s  .  co  m*/

    try {

        BeanInfo bi = Introspector.getBeanInfo(target.getClass());

        properties = bi.getPropertyDescriptors();

    } catch (IntrospectionException ex) {

        Tools.logException(HMEConfigurationPanel.class, ex, "PropertySheet: Couldn't introspect");

        return;

    }

    editors = new PropertyEditor[properties.length];

    values = new Object[properties.length];

    views = new Component[properties.length];

    labels = new JLabel[properties.length];

    for (int i = 0; i < properties.length; i++) {

        // Don't display hidden or expert properties.

        if (properties[i].isHidden() || properties[i].isExpert()) {

            continue;

        }

        String name = properties[i].getDisplayName();

        Class type = properties[i].getPropertyType();

        Method getter = properties[i].getReadMethod();

        Method setter = properties[i].getWriteMethod();

        // Only display read/write properties.

        if (getter == null || setter == null) {

            continue;

        }

        Component view = null;

        try {

            Object args[] = {};

            Object value = getter.invoke(target, args);

            values[i] = value;

            PropertyEditor editor = null;

            Class pec = properties[i].getPropertyEditorClass();

            if (pec != null) {

                try {

                    editor = (PropertyEditor) pec.newInstance();

                } catch (Exception ex) {

                    // Drop through.

                }

            }

            if (editor == null) {

                editor = PropertyEditorManager.findEditor(type);

            }

            editors[i] = editor;

            // If we can't edit this component, skip it.

            if (editor == null) {

                // If it's a user-defined property we give a warning.

                String getterClass = properties[i].getReadMethod().getDeclaringClass().getName();

                if (getterClass.indexOf("java.") != 0) {

                    log.error("Warning: Can't find public property editor for property \"" + name

                            + "\".  Skipping.");

                }

                continue;

            }

            // Don't try to set null values:

            if (value == null) {

                // If it's a user-defined property we give a warning.

                String getterClass = properties[i].getReadMethod().getDeclaringClass().getName();

                if (getterClass.indexOf("java.") != 0) {

                    log.error("Warning: Property \"" + name + "\" has null initial value.  Skipping.");

                }

                continue;

            }

            editor.setValue(value);

            // editor.addPropertyChangeListener(adaptor);

            // Now figure out how to display it...

            if (editor.isPaintable() && editor.supportsCustomEditor()) {

                view = new PropertyCanvas(frame, editor);

            } else if (editor.getTags() != null) {

                view = new PropertySelector(editor);

            } else if (editor.getAsText() != null) {

                String init = editor.getAsText();

                view = new PropertyText(editor);

            } else {

                log.error("Warning: Property \"" + name + "\" has non-displayabale editor.  Skipping.");

                continue;

            }

        } catch (InvocationTargetException ex) {

            Tools.logException(HMEConfigurationPanel.class, ex.getTargetException(),
                    "Skipping property " + name);

            continue;

        } catch (Exception ex) {

            Tools.logException(HMEConfigurationPanel.class, ex, "Skipping property " + name);

            continue;

        }

        labels[i] = new JLabel(WordUtils.capitalize(name), JLabel.RIGHT);

        // add(labels[i]);

        views[i] = view;

        // add(views[i]);

    }

    int validCounter = 0;

    for (int i = 0; i < labels.length; i++) {

        if (labels[i] != null)

            validCounter++;

    }

    String rowStrings = ""; // general

    if (validCounter > 0)

        rowStrings = "pref, ";

    else

        rowStrings = "pref";

    int counter = 0;

    for (int i = 0; i < labels.length; i++) {

        if (labels[i] != null) {

            if (++counter == (validCounter))

                rowStrings = rowStrings + "9dlu, " + "pref";

            else

                rowStrings = rowStrings + "9dlu, " + "pref, ";

        }

    }

    FormLayout layout = new FormLayout("right:pref, 3dlu, 50dlu:g, right:pref:grow", rowStrings);

    PanelBuilder builder = new PanelBuilder(layout);

    //DefaultFormBuilder builder = new DefaultFormBuilder(new FormDebugPanel(), layout);

    builder.setDefaultDialogBorder();

    CellConstraints cc = new CellConstraints();

    builder.addSeparator("General", cc.xyw(1, 1, 4));

    counter = 0;

    for (int i = 0; i < labels.length; i++) {

        if (labels[i] != null) {

            counter++;

            builder.add(labels[i], cc.xy(1, counter * 2 + 1));

            builder.add(views[i], cc.xy(3, counter * 2 + 1));

        }

    }

    JPanel panel = builder.getPanel();

    //FormDebugUtils.dumpAll(panel);

    add(panel);

}

From source file:de.escalon.hypermedia.spring.hydra.LinkListSerializer.java

/**
 * Writes bean description recursively./*  ww w .  j  a v  a 2s .c  o  m*/
 *
 * @param jgen
 *         to write to
 * @param currentVocab
 *         in context
 * @param valueType
 *         class of value
 * @param allRootParameters
 *         of the method that receives the request body
 * @param rootParameter
 *         the request body
 * @param currentCallValue
 *         the value at the current recursion level
 * @param propertyPath
 *         of the current recursion level
 * @throws IntrospectionException
 * @throws IOException
 */
private void recurseSupportedProperties(JsonGenerator jgen, String currentVocab, Class<?> valueType,
        ActionDescriptor allRootParameters, ActionInputParameter rootParameter, Object currentCallValue,
        String propertyPath) throws IntrospectionException, IOException {

    Map<String, ActionInputParameter> properties = new HashMap<String, ActionInputParameter>();

    // collect supported properties from ctor

    Constructor[] constructors = valueType.getConstructors();
    // find default ctor
    Constructor constructor = PropertyUtils.findDefaultCtor(constructors);
    // find ctor with JsonCreator ann
    if (constructor == null) {
        constructor = PropertyUtils.findJsonCreator(constructors, JsonCreator.class);
    }
    if (constructor == null) {
        // TODO this can be a generic collection, find a way to describe it
        LOG.warn("can't describe supported properties, no default constructor or JsonCreator found for type "
                + valueType.getName());
        return;
    }

    int parameterCount = constructor.getParameterTypes().length;
    if (parameterCount > 0) {
        Annotation[][] annotationsOnParameters = constructor.getParameterAnnotations();

        Class[] parameters = constructor.getParameterTypes();
        int paramIndex = 0;
        for (Annotation[] annotationsOnParameter : annotationsOnParameters) {
            for (Annotation annotation : annotationsOnParameter) {
                if (JsonProperty.class == annotation.annotationType()) {
                    JsonProperty jsonProperty = (JsonProperty) annotation;
                    // TODO use required attribute of JsonProperty
                    String paramName = jsonProperty.value();

                    Object propertyValue = PropertyUtils.getPropertyOrFieldValue(currentCallValue, paramName);

                    ActionInputParameter constructorParamInputParameter = new SpringActionInputParameter(
                            new MethodParameter(constructor, paramIndex), propertyValue);

                    // TODO collect ctor params, setter params and process
                    // TODO then handle single, collection and bean for both
                    properties.put(paramName, constructorParamInputParameter);
                    paramIndex++; // increase for each @JsonProperty
                }
            }
        }
        Assert.isTrue(parameters.length == paramIndex, "not all constructor arguments of @JsonCreator "
                + constructor.getName() + " are annotated with @JsonProperty");
    }

    // collect supported properties from setters

    // TODO support Option provider by other method args?
    final BeanInfo beanInfo = Introspector.getBeanInfo(valueType);
    final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
    // TODO collection and map
    // TODO distinguish which properties should be printed as supported - now just setters
    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
        final Method writeMethod = propertyDescriptor.getWriteMethod();
        if (writeMethod == null) {
            continue;
        }
        // TODO: the property name must be a valid URI - need to check context for terms?
        String propertyName = getWritableExposedPropertyOrPropertyName(propertyDescriptor);

        Object propertyValue = PropertyUtils.getPropertyOrFieldValue(currentCallValue,
                propertyDescriptor.getName());

        MethodParameter methodParameter = new MethodParameter(propertyDescriptor.getWriteMethod(), 0);
        ActionInputParameter propertySetterInputParameter = new SpringActionInputParameter(methodParameter,
                propertyValue);

        properties.put(propertyName, propertySetterInputParameter);
    }

    // write all supported properties
    // TODO we are using the annotatedParameter.parameterName but should use the key of properties here:
    for (ActionInputParameter annotatedParameter : properties.values()) {
        String nextPropertyPathLevel = propertyPath.isEmpty() ? annotatedParameter.getParameterName()
                : propertyPath + '.' + annotatedParameter.getParameterName();
        if (DataType.isSingleValueType(annotatedParameter.getParameterType())) {

            final Object[] possiblePropertyValues = rootParameter.getPossibleValues(allRootParameters);

            if (rootParameter.isIncluded(nextPropertyPathLevel)
                    && !rootParameter.isExcluded(nextPropertyPathLevel)) {
                writeSupportedProperty(jgen, currentVocab, annotatedParameter,
                        annotatedParameter.getParameterName(), possiblePropertyValues);
            }
            // TODO collections?
            //                        } else if (DataType.isArrayOrCollection(parameterType)) {
            //                            Object[] callValues = rootParameter.getValues();
            //                            int items = callValues.length;
            //                            for (int i = 0; i < items; i++) {
            //                                Object value;
            //                                if (i < callValues.length) {
            //                                    value = callValues[i];
            //                                } else {
            //                                    value = null;
            //                                }
            //                                recurseSupportedProperties(jgen, currentVocab, rootParameter
            // .getParameterType(),
            //                                        allRootParameters, rootParameter, value);
            //                            }
        } else {
            jgen.writeStartObject();
            jgen.writeStringField("hydra:property", annotatedParameter.getParameterName());
            // TODO: is the property required -> for bean props we need the Access annotation to express that
            jgen.writeObjectFieldStart(getPropertyOrClassNameInVocab(currentVocab, "rangeIncludes",
                    LdContextFactory.HTTP_SCHEMA_ORG, "schema:"));
            Expose expose = AnnotationUtils.getAnnotation(annotatedParameter.getParameterType(), Expose.class);
            String subClass;
            if (expose != null) {
                subClass = expose.value();
            } else {
                subClass = annotatedParameter.getParameterType().getSimpleName();
            }
            jgen.writeStringField(getPropertyOrClassNameInVocab(currentVocab, "subClassOf",
                    "http://www.w3" + ".org/2000/01/rdf-schema#", "rdfs:"), subClass);

            jgen.writeArrayFieldStart("hydra:supportedProperty");

            Object propertyValue = PropertyUtils.getPropertyOrFieldValue(currentCallValue,
                    annotatedParameter.getParameterName());

            recurseSupportedProperties(jgen, currentVocab, annotatedParameter.getParameterType(),
                    allRootParameters, rootParameter, propertyValue, nextPropertyPathLevel);
            jgen.writeEndArray();

            jgen.writeEndObject();
            jgen.writeEndObject();
        }
    }
}

From source file:de.micromata.genome.db.jpa.logging.BaseJpaLoggingImpl.java

/**
 * Inits the./* w ww . j av a  2  s . c  o  m*/
 */
protected void initProps() {
    final BeanInfo bi;
    try {
        bi = Introspector.getBeanInfo(getMasterClass());
    } catch (IntrospectionException e) {
        log.error("unable to introspect hibernate DO for logging -> no searchable fields will be available", e);
        return;
    }

    for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
        if (pd.getReadMethod() == null || pd.getWriteMethod() == null) {
            continue;
        }
        EntityLogSearchAttribute ent = pd.getReadMethod().getAnnotation(EntityLogSearchAttribute.class);
        if (ent == null) {
            continue;
        }
        Column col = pd.getReadMethod().getAnnotation(Column.class);
        if (col == null) {
            log.warn("Found EntityLogSearchAttribute but no Column: " + pd);
            continue;
        }
        for (String en : ent.enumName()) {
            searchableAttributeProperties.put(en, new SearchColumnDesc(pd, col.length()));
        }
    }
}

From source file:com.temenos.interaction.media.hal.HALProvider.java

/** populate a Map from a java bean
 *  TODO implement nested structures and collections
 *//*from  w  ww .j  a va  2  s  .c o  m*/
protected void buildFromBean(Map<String, Object> map, Object bean, String entityName) {
    EntityMetadata entityMetadata = metadata.getEntityMetadata(entityName);
    if (entityMetadata == null)
        throw new IllegalStateException("Entity metadata could not be found [" + entityName + "]");

    try {
        BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
        for (PropertyDescriptor propertyDesc : beanInfo.getPropertyDescriptors()) {
            String propertyName = propertyDesc.getName();
            if (entityMetadata.getPropertyVocabulary(propertyName) != null) {
                Object value = propertyDesc.getReadMethod().invoke(bean);
                map.put(propertyName, value);
            }
        }
    } catch (IllegalArgumentException e) {
        logger.error("Error accessing bean property", e);
    } catch (IntrospectionException e) {
        logger.error("Error accessing bean property", e);
    } catch (IllegalAccessException e) {
        logger.error("Error accessing bean property", e);
    } catch (InvocationTargetException e) {
        logger.error("Error accessing bean property", e);
    }
}

From source file:org.rhq.scripting.javascript.JavascriptCompletor.java

private Map<String, List<Object>> findJavaBeanContextMatches(Object baseObject, Class<?> baseObjectClass,
        String start) throws IntrospectionException {

    Map<String, List<Object>> found = new HashMap<String, List<Object>>();

    BeanInfo info = null;
    if (baseObjectClass.isInterface() || baseObjectClass.equals(Object.class)) {
        info = Introspector.getBeanInfo(baseObjectClass);
    } else {// w  w w.  j  a v a  2s .  co m
        info = Introspector.getBeanInfo(baseObjectClass, Object.class);
    }

    Set<Method> methodsCovered = new HashSet<Method>();

    PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
    for (PropertyDescriptor desc : descriptors) {
        if (desc.getName().startsWith(start) && (!IGNORED_METHODS.contains(desc.getName()))) {

            List<Object> list = found.get(desc.getName());
            if (list == null) {
                list = new ArrayList<Object>();
                found.put(desc.getName(), list);
            }
            list.add(desc);

            methodsCovered.add(desc.getReadMethod());
            methodsCovered.add(desc.getWriteMethod());
        }
    }

    MethodDescriptor[] methods = info.getMethodDescriptors();
    for (MethodDescriptor desc : methods) {
        if (desc.getName().startsWith(start) && !methodsCovered.contains(desc.getMethod())
                && !desc.getName().startsWith("_d") && !IGNORED_METHODS.contains(desc.getName())) {

            Method m = desc.getMethod();

            List<Object> list = found.get(desc.getName());
            if (list == null) {
                list = new ArrayList<Object>();
                found.put(desc.getName(), list);
            }
            list.add(m);
        }
    }

    return found;
}

From source file:org.apache.jmeter.testbeans.gui.GenericTestBeanCustomizer.java

/**
 * Create a customizer for a given test bean type.
 *
 * @param testBeanClass//from   www . j a v a  2  s  .  c  o m
 *            a subclass of TestBean
 * @see org.apache.jmeter.testbeans.TestBean
 */
GenericTestBeanCustomizer(BeanInfo beanInfo) {
    super();

    this.beanInfo = beanInfo;

    // Get and sort the property descriptors:
    descriptors = beanInfo.getPropertyDescriptors();
    Arrays.sort(descriptors, new PropertyComparator(beanInfo));

    // Obtain the propertyEditors:
    editors = new PropertyEditor[descriptors.length];
    int scriptLanguageIndex = 0;
    int textAreaEditorIndex = 0;
    for (int i = 0; i < descriptors.length; i++) { // Index is also used for accessing editors array
        PropertyDescriptor descriptor = descriptors[i];
        String name = descriptor.getName();

        // Don't get editors for hidden or non-read-write properties:
        if (TestBeanHelper.isDescriptorIgnored(descriptor)) {
            log.debug("Skipping editor for property " + name);
            editors[i] = null;
            continue;
        }

        PropertyEditor propertyEditor;
        Object guiType = descriptor.getValue(GUITYPE);
        if (guiType instanceof TypeEditor) {
            propertyEditor = ((TypeEditor) guiType).getInstance(descriptor);
        } else if (guiType instanceof Class && Enum.class.isAssignableFrom((Class<?>) guiType)) {
            @SuppressWarnings("unchecked") // we check the class type above
            final Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) guiType;
            propertyEditor = new EnumEditor(descriptor, enumClass,
                    (ResourceBundle) descriptor.getValue(GenericTestBeanCustomizer.RESOURCE_BUNDLE));
        } else {
            Class<?> editorClass = descriptor.getPropertyEditorClass();
            if (log.isDebugEnabled()) {
                log.debug("Property " + name + " has editor class " + editorClass);
            }

            if (editorClass != null) {
                try {
                    propertyEditor = (PropertyEditor) editorClass.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    log.error("Can't create property editor.", e);
                    throw new Error(e.toString());
                }
            } else {
                Class<?> c = descriptor.getPropertyType();
                propertyEditor = PropertyEditorManager.findEditor(c);
            }
        }

        if (propertyEditor == null) {
            log.warn("No editor for property: " + name + " type: " + descriptor.getPropertyType() + " in bean: "
                    + beanInfo.getBeanDescriptor().getDisplayName());
            editors[i] = null;
            continue;
        }

        if (log.isDebugEnabled()) {
            log.debug("Property " + name + " has property editor " + propertyEditor);
        }

        validateAttributes(descriptor, propertyEditor);

        if (!propertyEditor.supportsCustomEditor()) {
            propertyEditor = createWrapperEditor(propertyEditor, descriptor);

            if (log.isDebugEnabled()) {
                log.debug("Editor for property " + name + " is wrapped in " + propertyEditor);
            }
        }
        if (propertyEditor instanceof TestBeanPropertyEditor) {
            ((TestBeanPropertyEditor) propertyEditor).setDescriptor(descriptor);
        }

        if (propertyEditor instanceof TextAreaEditor) {
            textAreaEditorIndex = i;
        }
        if (propertyEditor.getCustomEditor() instanceof JScrollPane) {
            scrollerCount++;
        }

        editors[i] = propertyEditor;

        // Initialize the editor with the provided default value or null:
        setEditorValue(i, descriptor.getValue(DEFAULT));

        if (name.equals("scriptLanguage")) {
            scriptLanguageIndex = i;
        }

    }
    // In case of BSF and JSR elements i want to add textAreaEditor as a listener to scriptLanguage ComboBox.
    String beanName = this.beanInfo.getBeanDescriptor().getName();
    if (beanName.startsWith("BSF") || beanName.startsWith("JSR223")) { // $NON-NLS-1$ $NON-NLS-2$
        WrapperEditor we = (WrapperEditor) editors[scriptLanguageIndex];
        TextAreaEditor tae = (TextAreaEditor) editors[textAreaEditorIndex];
        we.addChangeListener(tae);
    }

    // Obtain message formats:
    propertyFieldLabelMessage = new MessageFormat(JMeterUtils.getResString("property_as_field_label")); //$NON-NLS-1$
    propertyToolTipMessage = new MessageFormat(JMeterUtils.getResString("property_tool_tip")); //$NON-NLS-1$

    // Initialize the GUI:
    init();
}

From source file:ResultSetIterator.java

/**
 * Returns a PropertyDescriptor[] for the given Class.
 *
 * @param c The Class to retrieve PropertyDescriptors for.
 * @return A PropertyDescriptor[] describing the Class.
 * @throws SQLException if introspection failed.
 *//* w w  w  .  ja va2  s.  co  m*/
private PropertyDescriptor[] propertyDescriptors(Class c) throws SQLException {
    // Introspector caches BeanInfo classes for better performance
    BeanInfo beanInfo = null;
    try {
        beanInfo = Introspector.getBeanInfo(c);

    } catch (IntrospectionException e) {
        throw new SQLException("Bean introspection failed: " + e.getMessage());
    }

    return beanInfo.getPropertyDescriptors();
}

From source file:com.mylife.hbase.mapper.HBaseEntityMapper.java

/**
 * Helper method to lookup getter methods for each annotated Field
 * /*from  ww w  .j a v a 2 s.  c om*/
 * Note: This requires a proper bean pattern getter method in the annotatedClass for the annotatedField.
 * 
 * @param annotatedClass
 * @param annotatedFields
 * @return
 */
private ImmutableMap<Field, Method> fieldsToGetterMap(final Class<?> annotatedClass,
        final ImmutableSet<Field> annotatedFields) {
    final ImmutableMap.Builder<Field, Method> mappings = new ImmutableMap.Builder<Field, Method>();
    final BeanInfo beanInfo;
    try {
        beanInfo = Introspector.getBeanInfo(annotatedClass);
    } catch (IntrospectionException e) {
        // should never happen
        LOG.error(e);
        throw new RuntimeException(e);
    }

    final ArrayList<PropertyDescriptor> propertyDescriptors = Lists
            .newArrayList(beanInfo.getPropertyDescriptors());

    for (final Field field : annotatedFields) {
        for (int i = 0; i < propertyDescriptors.size(); i++) {
            if (field.getName().equals(propertyDescriptors.get(i).getName())) {
                mappings.put(field, propertyDescriptors.get(i).getReadMethod());
                propertyDescriptors.remove(i);
                i--;
            }
        }
    }

    return mappings.build();
}

From source file:org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils.java

/**
 * @return the {@link PropertyDescriptor}'s for given {@link Class}.
 *///  ww  w  . jav  a  2 s.  c  o  m
public static List<PropertyDescriptor> getPropertyDescriptors(BeanInfo beanInfo, Class<?> componentClass)
        throws Exception {
    // check cache
    {
        List<PropertyDescriptor> descriptors = m_propertyDescriptorsCache.get(componentClass);
        if (descriptors != null) {
            return descriptors;
        }
    }
    // prepare descriptions
    List<PropertyDescriptor> descriptors = Lists.newArrayList();
    // if there is BeanInfo, try to use it
    if (beanInfo != null) {
        Collections.addAll(descriptors, beanInfo.getPropertyDescriptors());
        // remove indexed properties
        for (Iterator<PropertyDescriptor> I = descriptors.iterator(); I.hasNext();) {
            PropertyDescriptor descriptor = I.next();
            if (descriptor instanceof IndexedPropertyDescriptor) {
                I.remove();
            }
        }
    }
    // prepare getters/setters
    Map<String, Method> propertyToGetter = Maps.newTreeMap();
    Map<String, Method> propertyToSetter = Maps.newTreeMap();
    // append existing getters/setters
    for (PropertyDescriptor propertyDescriptor : descriptors) {
        Method readMethod = getReadMethod(propertyDescriptor);
        Method writeMethod = getWriteMethod(propertyDescriptor);
        if (readMethod != null) {
            String propertyName = getQualifiedPropertyName(readMethod);
            propertyToGetter.put(propertyName, readMethod);
            propertyDescriptor.setName(propertyName);
        }
        if (writeMethod != null) {
            String propertyName = getQualifiedPropertyName(writeMethod);
            propertyToSetter.put(propertyName, writeMethod);
            propertyDescriptor.setName(propertyName);
        }
    }
    // append missing methods (most probably protected)
    Set<String> newPropertyNames = Sets.newTreeSet();
    appendPropertyComponents(componentClass, newPropertyNames, propertyToGetter, propertyToSetter);
    // create PropertyDescriptor's for new getters/setters
    for (String propertyName : newPropertyNames) {
        addPropertyDescriptor(descriptors, propertyName, propertyToGetter, propertyToSetter);
    }
    useSimplePropertyNamesWherePossible(descriptors);
    makeMethodsAccessible(descriptors);
    // OK, final result
    m_propertyDescriptorsCache.put(componentClass, descriptors);
    return descriptors;
}