Example usage for java.beans PropertyDescriptor getName

List of usage examples for java.beans PropertyDescriptor getName

Introduction

In this page you can find the example usage for java.beans PropertyDescriptor getName.

Prototype

public String getName() 

Source Link

Document

Gets the programmatic name of this feature.

Usage

From source file:org.jdal.swing.ListTableModel.java

/** 
 * Initialize table. Load propertyDescriptors based on columNames or 
 * model introspection. /*www . jav a 2s.c  o m*/
 */
// FIXME: PropertyDescriptors  are now unused, review to remove.
public void init() {
    if (modelClass == null) {
        log.warn("Cannot initilize without  modelClass, set a list of models o specify a model class");
        return;
    }

    columnCount = 0;

    if (usingIntrospection) {
        pds = Arrays.asList(BeanUtils.getPropertyDescriptors(modelClass));
        Collections.reverse(pds);
        columnNames = new ArrayList<String>(pds.size());
        displayNames = new ArrayList<String>(pds.size());

        for (PropertyDescriptor propertyDescriptor : pds) {
            columnNames.add(propertyDescriptor.getName());
            displayNames.add(propertyDescriptor.getDisplayName());
        }
    }

    else {
        pds = new ArrayList<PropertyDescriptor>(columnNames.size());
        for (String name : columnNames) {
            PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(modelClass, name);
            if (pd == null)
                throw new RuntimeException(
                        "Invalid property [" + name + "]" + " for model class [" + modelClass.getName() + "]");
            pds.add(pd);
        }
    }

    columnCount += pds.size();

    if (usingChecks) {
        columnCount++;
        buildCheckArray();
    }

    if (usingActions) {
        columnCount += actions.size();
    }
}

From source file:com.cnd.greencube.server.dao.jdbc.JdbcDAO.java

@SuppressWarnings("rawtypes")
private Column2Property getIdFromObject(Class clazz) throws Exception {

    // ???/*from w  w w.j a v a 2  s.  c  o  m*/
    for (Field field : clazz.getDeclaredFields()) {
        String columnName = null;
        Annotation[] annotations = field.getDeclaredAnnotations();
        for (Annotation a : annotations) {
            if (a instanceof Id) {
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                Column2Property c = new Column2Property();
                c.propertyName = pd.getName();
                c.setterMethodName = pd.getWriteMethod().getName();
                c.getterMethodName = pd.getReadMethod().getName();
                c.columnName = columnName;
                return c;

            }
        }
    }
    return null;
}

From source file:ca.sqlpower.sqlobject.BaseSQLObjectTestCase.java

/**
 * @throws IllegalArgumentException//www .jav a2 s. c o m
 * @throws IllegalAccessException
 * @throws InvocationTargetException
 * @throws NoSuchMethodException
 * @throws SQLObjectException 
 */
public void testAllSettersAreUndoable() throws IllegalArgumentException, IllegalAccessException,
        InvocationTargetException, NoSuchMethodException, SQLObjectException {

    SQLObject so = getSQLObjectUnderTest();
    propertiesToIgnoreForUndo.add("referenceCount");
    propertiesToIgnoreForUndo.add("populated");
    propertiesToIgnoreForUndo.add("exportedKeysPopulated");
    propertiesToIgnoreForUndo.add("importedKeysPopulated");
    propertiesToIgnoreForUndo.add("columnsPopulated");
    propertiesToIgnoreForUndo.add("indicesPopulated");
    propertiesToIgnoreForUndo.add("SQLObjectListeners");
    propertiesToIgnoreForUndo.add("children");
    propertiesToIgnoreForUndo.add("parent");
    propertiesToIgnoreForUndo.add("parentDatabase");
    propertiesToIgnoreForUndo.add("class");
    propertiesToIgnoreForUndo.add("childCount");
    propertiesToIgnoreForUndo.add("undoEventListeners");
    propertiesToIgnoreForUndo.add("connection");
    propertiesToIgnoreForUndo.add("typeMap");
    propertiesToIgnoreForUndo.add("secondaryChangeMode");
    propertiesToIgnoreForUndo.add("zoomInAction");
    propertiesToIgnoreForUndo.add("zoomOutAction");
    propertiesToIgnoreForUndo.add("magicEnabled");
    propertiesToIgnoreForUndo.add("deleteRule");
    propertiesToIgnoreForUndo.add("updateRule");
    propertiesToIgnoreForUndo.add("tableContainer");
    propertiesToIgnoreForUndo.add("session");
    propertiesToIgnoreForUndo.add("workspaceContainer");
    propertiesToIgnoreForUndo.add("runnableDispatcher");
    propertiesToIgnoreForUndo.add("foregroundThread");

    if (so instanceof SQLDatabase) {
        // should be handled in the Datasource
        propertiesToIgnoreForUndo.add("name");
    }

    SPObjectUndoManager undoManager = new SPObjectUndoManager(so);
    List<PropertyDescriptor> settableProperties;
    settableProperties = Arrays.asList(PropertyUtils.getPropertyDescriptors(so.getClass()));
    if (so instanceof SQLDatabase) {
        // should be handled in the Datasource
        settableProperties.remove("name");
    }
    for (PropertyDescriptor property : settableProperties) {
        Object oldVal;
        if (propertiesToIgnoreForUndo.contains(property.getName()))
            continue;

        try {
            oldVal = PropertyUtils.getSimpleProperty(so, property.getName());
            if (property.getWriteMethod() == null) {
                continue;
            }
        } catch (NoSuchMethodException e) {
            System.out.println(
                    "Skipping non-settable property " + property.getName() + " on " + so.getClass().getName());
            continue;
        }
        Object newVal; // don't init here so compiler can warn if the following code doesn't always give it a value
        if (property.getPropertyType() == Integer.TYPE || property.getPropertyType() == Integer.class) {
            if (oldVal != null) {
                newVal = ((Integer) oldVal) + 1;
            } else {
                newVal = 1;
            }
        } else if (property.getPropertyType() == String.class) {
            // make sure it's unique
            newVal = "new " + oldVal;

        } else if (property.getPropertyType() == Boolean.TYPE || property.getPropertyType() == Boolean.class) {
            if (oldVal == null) {
                newVal = Boolean.TRUE;
            } else {
                newVal = new Boolean(!((Boolean) oldVal).booleanValue());
            }
        } else if (property.getPropertyType() == SQLCatalog.class) {
            newVal = new SQLCatalog(new SQLDatabase(), "This is a new catalog");
        } else if (property.getPropertyType() == SPDataSource.class) {
            newVal = new JDBCDataSource(getPLIni());
            ((SPDataSource) newVal).setName("test");
            ((SPDataSource) newVal).setDisplayName("test");
            ((JDBCDataSource) newVal).setUser("a");
            ((JDBCDataSource) newVal).setPass("b");
            ((JDBCDataSource) newVal).getParentType().setJdbcDriver(MockJDBCDriver.class.getName());
            ((JDBCDataSource) newVal).setUrl("jdbc:mock:tables=tab1,tab2");
        } else if (property.getPropertyType() == JDBCDataSource.class) {
            newVal = new JDBCDataSource(getPLIni());
            ((SPDataSource) newVal).setName("test");
            ((SPDataSource) newVal).setDisplayName("test");
            ((JDBCDataSource) newVal).setUser("a");
            ((JDBCDataSource) newVal).setPass("b");
            ((JDBCDataSource) newVal).getParentType().setJdbcDriver(MockJDBCDriver.class.getName());
            ((JDBCDataSource) newVal).setUrl("jdbc:mock:tables=tab1,tab2");
        } else if (property.getPropertyType() == SQLTable.class) {
            newVal = new SQLTable();
        } else if (property.getPropertyType() == SQLColumn.class) {
            newVal = new SQLColumn();
        } else if (property.getPropertyType() == SQLIndex.class) {
            newVal = new SQLIndex();
        } else if (property.getPropertyType() == SQLRelationship.SQLImportedKey.class) {
            SQLRelationship rel = new SQLRelationship();
            newVal = rel.getForeignKey();
        } else if (property.getPropertyType() == SQLRelationship.Deferrability.class) {
            if (oldVal == SQLRelationship.Deferrability.INITIALLY_DEFERRED) {
                newVal = SQLRelationship.Deferrability.NOT_DEFERRABLE;
            } else {
                newVal = SQLRelationship.Deferrability.INITIALLY_DEFERRED;
            }
        } else if (property.getPropertyType() == SQLIndex.AscendDescend.class) {
            if (oldVal == SQLIndex.AscendDescend.ASCENDING) {
                newVal = SQLIndex.AscendDescend.DESCENDING;
            } else {
                newVal = SQLIndex.AscendDescend.ASCENDING;
            }
        } else if (property.getPropertyType() == Throwable.class) {
            newVal = new Throwable();
        } else if (property.getPropertyType() == BasicSQLType.class) {
            if (oldVal != BasicSQLType.OTHER) {
                newVal = BasicSQLType.OTHER;
            } else {
                newVal = BasicSQLType.TEXT;
            }
        } else if (property.getPropertyType() == UserDefinedSQLType.class) {
            newVal = new UserDefinedSQLType();
        } else if (property.getPropertyType() == SQLTypeConstraint.class) {
            if (oldVal != SQLTypeConstraint.NONE) {
                newVal = SQLTypeConstraint.NONE;
            } else {
                newVal = SQLTypeConstraint.CHECK;
            }
        } else if (property.getPropertyType() == SQLCheckConstraint.class) {
            newVal = new SQLCheckConstraint("check constraint name", "check constraint condition");
        } else if (property.getPropertyType() == SQLEnumeration.class) {
            newVal = new SQLEnumeration("some enumeration");
        } else if (property.getPropertyType() == String[].class) {
            newVal = new String[3];
        } else if (property.getPropertyType() == PropertyType.class) {
            if (oldVal != PropertyType.NOT_APPLICABLE) {
                newVal = PropertyType.NOT_APPLICABLE;
            } else {
                newVal = PropertyType.VARIABLE;
            }
        } else {
            throw new RuntimeException("This test case lacks a value for " + property.getName() + " (type "
                    + property.getPropertyType().getName() + ") from " + so.getClass());
        }

        int oldChangeCount = undoManager.getUndoableEditCount();

        try {
            BeanUtils.copyProperty(so, property.getName(), newVal);

            // some setters fire multiple events (they change more than one property)  but only register one as an undo
            assertEquals(
                    "Event for set " + property.getName() + " on " + so.getClass().getName()
                            + " added multiple (" + undoManager.printUndoVector() + ") undos!",
                    oldChangeCount + 1, undoManager.getUndoableEditCount());

        } catch (InvocationTargetException e) {
            System.out.println("(non-fatal) Failed to write property '" + property.getName() + " to type "
                    + so.getClass().getName());
        }
    }
}

From source file:QueryRunner.java

/**
 * Fill the <code>PreparedStatement</code> replacement parameters with the
 * given object's bean property values.//  w ww. j a  va  2s  .  c  o  m
 * 
 * @param stmt
 *            PreparedStatement to fill
 * @param bean
 *            a JavaBean object
 * @param properties
 *            an ordered array of properties; this gives the order to insert
 *            values in the statement
 * @throws SQLException
 *             if a database access error occurs
 */
public void fillStatementWithBean(PreparedStatement stmt, Object bean, PropertyDescriptor[] properties)
        throws SQLException {
    Object[] params = new Object[properties.length];
    for (int i = 0; i < properties.length; i++) {
        PropertyDescriptor property = properties[i];
        Object value = null;
        Method method = property.getReadMethod();
        if (method == null) {
            throw new RuntimeException(
                    "No read method for bean property " + bean.getClass() + " " + property.getName());
        }
        try {
            value = method.invoke(bean, new Object[0]);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Couldn't invoke method: " + method, e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("Couldn't invoke method with 0 arguments: " + method, e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Couldn't invoke method: " + method, e);
        }
        params[i] = value;
    }
    fillStatement(stmt, params);
}

From source file:ca.sqlpower.sqlobject.BaseSQLObjectTestCase.java

/**
 * XXX This test should use the {@link GenericNewValueMaker} as it has it's own mini
 * version inside it. This test should also be using the annotations to decide which 
 * setters can fire events.//from   www  . j  a  v a 2s .  co  m
 * 
 * @throws IllegalArgumentException
 * @throws IllegalAccessException
 * @throws InvocationTargetException
 * @throws NoSuchMethodException
 * @throws SQLObjectException
 */
public void testAllSettersGenerateEvents() throws IllegalArgumentException, IllegalAccessException,
        InvocationTargetException, NoSuchMethodException, SQLObjectException {
    SQLObject so = getSQLObjectUnderTest();
    so.populate();

    propertiesToIgnoreForEventGeneration.addAll(getPropertiesToIgnoreForEvents());

    //Ignored because we expect the object to be populated.
    propertiesToIgnoreForEventGeneration.add("exportedKeysPopulated");
    propertiesToIgnoreForEventGeneration.add("importedKeysPopulated");
    propertiesToIgnoreForEventGeneration.add("columnsPopulated");
    propertiesToIgnoreForEventGeneration.add("indicesPopulated");

    CountingSQLObjectListener listener = new CountingSQLObjectListener();
    SQLPowerUtils.listenToHierarchy(so, listener);

    if (so instanceof SQLDatabase) {
        // should be handled in the Datasource
        propertiesToIgnoreForEventGeneration.add("name");
    }

    List<PropertyDescriptor> settableProperties;

    settableProperties = Arrays.asList(PropertyUtils.getPropertyDescriptors(so.getClass()));

    for (PropertyDescriptor property : settableProperties) {
        Object oldVal;
        if (propertiesToIgnoreForEventGeneration.contains(property.getName()))
            continue;

        try {
            oldVal = PropertyUtils.getSimpleProperty(so, property.getName());
            // check for a setter
            if (property.getWriteMethod() == null) {
                continue;
            }

        } catch (NoSuchMethodException e) {
            System.out.println(
                    "Skipping non-settable property " + property.getName() + " on " + so.getClass().getName());
            continue;
        }
        Object newVal; // don't init here so compiler can warn if the following code doesn't always give it a value
        if (property.getPropertyType() == Integer.TYPE || property.getPropertyType() == Integer.class) {
            if (oldVal != null) {
                newVal = ((Integer) oldVal) + 1;
            } else {
                newVal = 1;
            }
        } else if (property.getPropertyType() == String.class) {
            // make sure it's unique
            newVal = "new " + oldVal;

        } else if (property.getPropertyType() == Boolean.TYPE || property.getPropertyType() == Boolean.class) {
            if (oldVal == null) {
                newVal = Boolean.TRUE;
            } else {
                newVal = new Boolean(!((Boolean) oldVal).booleanValue());
            }
        } else if (property.getPropertyType() == SQLCatalog.class) {
            newVal = new SQLCatalog(new SQLDatabase(), "This is a new catalog");
        } else if (property.getPropertyType() == SPDataSource.class) {
            newVal = new JDBCDataSource(getPLIni());
            ((SPDataSource) newVal).setName("test");
            ((SPDataSource) newVal).setDisplayName("test");
            ((JDBCDataSource) newVal).setUser("a");
            ((JDBCDataSource) newVal).setPass("b");
            ((JDBCDataSource) newVal).getParentType().setJdbcDriver(MockJDBCDriver.class.getName());
            ((JDBCDataSource) newVal).setUrl("jdbc:mock:tables=tab1");
        } else if (property.getPropertyType() == JDBCDataSource.class) {
            newVal = new JDBCDataSource(getPLIni());
            ((SPDataSource) newVal).setName("test");
            ((SPDataSource) newVal).setDisplayName("test");
            ((JDBCDataSource) newVal).setUser("a");
            ((JDBCDataSource) newVal).setPass("b");
            ((JDBCDataSource) newVal).getParentType().setJdbcDriver(MockJDBCDriver.class.getName());
            ((JDBCDataSource) newVal).setUrl("jdbc:mock:tables=tab1");
        } else if (property.getPropertyType() == SQLTable.class) {
            newVal = new SQLTable();
        } else if (property.getPropertyType() == SQLColumn.class) {
            newVal = new SQLColumn();
        } else if (property.getPropertyType() == SQLIndex.class) {
            newVal = new SQLIndex();
        } else if (property.getPropertyType() == SQLRelationship.SQLImportedKey.class) {
            SQLRelationship rel = new SQLRelationship();
            newVal = rel.getForeignKey();
        } else if (property.getPropertyType() == SQLRelationship.Deferrability.class) {
            if (oldVal == SQLRelationship.Deferrability.INITIALLY_DEFERRED) {
                newVal = SQLRelationship.Deferrability.NOT_DEFERRABLE;
            } else {
                newVal = SQLRelationship.Deferrability.INITIALLY_DEFERRED;
            }
        } else if (property.getPropertyType() == SQLRelationship.UpdateDeleteRule.class) {
            if (oldVal == SQLRelationship.UpdateDeleteRule.CASCADE) {
                newVal = SQLRelationship.UpdateDeleteRule.RESTRICT;
            } else {
                newVal = SQLRelationship.UpdateDeleteRule.CASCADE;
            }
        } else if (property.getPropertyType() == SQLIndex.AscendDescend.class) {
            if (oldVal == SQLIndex.AscendDescend.ASCENDING) {
                newVal = SQLIndex.AscendDescend.DESCENDING;
            } else {
                newVal = SQLIndex.AscendDescend.ASCENDING;
            }
        } else if (property.getPropertyType() == Throwable.class) {
            newVal = new Throwable();
        } else if (property.getPropertyType() == BasicSQLType.class) {
            if (oldVal != BasicSQLType.OTHER) {
                newVal = BasicSQLType.OTHER;
            } else {
                newVal = BasicSQLType.TEXT;
            }
        } else if (property.getPropertyType() == UserDefinedSQLType.class) {
            newVal = new UserDefinedSQLType();
        } else if (property.getPropertyType() == SQLTypeConstraint.class) {
            if (oldVal != SQLTypeConstraint.NONE) {
                newVal = SQLTypeConstraint.NONE;
            } else {
                newVal = SQLTypeConstraint.CHECK;
            }
        } else if (property.getPropertyType() == String[].class) {
            newVal = new String[3];
        } else if (property.getPropertyType() == PropertyType.class) {
            if (oldVal != PropertyType.NOT_APPLICABLE) {
                newVal = PropertyType.NOT_APPLICABLE;
            } else {
                newVal = PropertyType.VARIABLE;
            }
        } else if (property.getPropertyType() == List.class) {
            newVal = Arrays.asList("one", "two");
        } else {
            throw new RuntimeException("This test case lacks a value for " + property.getName() + " (type "
                    + property.getPropertyType().getName() + ") from " + so.getClass() + " on property "
                    + property.getDisplayName());
        }

        int oldChangeCount = listener.getChangedCount();

        try {
            System.out.println("Setting property '" + property.getName() + "' to '" + newVal + "' ("
                    + newVal.getClass().getName() + ")");
            BeanUtils.copyProperty(so, property.getName(), newVal);

            // some setters fire multiple events (they change more than one property)
            assertTrue(
                    "Event for set " + property.getName() + " on " + so.getClass().getName() + " didn't fire!",
                    listener.getChangedCount() > oldChangeCount);
            if (listener.getChangedCount() == oldChangeCount + 1) {
                assertEquals("Property name mismatch for " + property.getName() + " in " + so.getClass(),
                        property.getName(), ((PropertyChangeEvent) listener.getLastEvent()).getPropertyName());
                assertEquals("New value for " + property.getName() + " was wrong", newVal,
                        ((PropertyChangeEvent) listener.getLastEvent()).getNewValue());
            }
        } catch (InvocationTargetException e) {
            System.out.println("(non-fatal) Failed to write property '" + property.getName() + " to type "
                    + so.getClass().getName());
        }
    }
}

From source file:com.maomao.framework.dao.jdbc.JdbcDAO.java

@SuppressWarnings("rawtypes")
private Column2Property getIdFromObject(Class clazz) throws Exception {

    // ???//from w  w  w  .  jav a2  s  . c  o m
    Column2Property c = null;
    for (Field field : clazz.getDeclaredFields()) {
        String columnName = null;
        Annotation[] annotations = field.getDeclaredAnnotations();
        for (Annotation a : annotations) {
            if (a instanceof Id) {
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                c = new Column2Property();
                c.propertyName = pd.getName();
                c.setterMethodName = pd.getWriteMethod().getName();
                c.getterMethodName = pd.getReadMethod().getName();
                c.columnName = columnName;
                break;
            }
        }
    }

    if (c == null) {
        Class superClass = clazz.getSuperclass();
        for (Field field : superClass.getDeclaredFields()) {
            String columnName = null;
            Annotation[] annotations = field.getDeclaredAnnotations();
            for (Annotation a : annotations) {
                if (a instanceof Id) {
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), superClass);
                    c = new Column2Property();
                    c.propertyName = pd.getName();
                    c.setterMethodName = pd.getWriteMethod().getName();
                    c.getterMethodName = pd.getReadMethod().getName();
                    c.columnName = columnName;
                    break;

                }
            }
        }
    }

    return c;
}

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  w  w  .  j  av  a  2s  .  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:cn.chenlichao.web.ssm.service.impl.BaseServiceImpl.java

@Override
public PageResults<E> queryPage(PageParams<E> pageParams) {
    if (pageParams == null) {
        throw new IllegalArgumentException("?null");
    }//from w ww  .j a v  a  2  s.co m
    LOGGER.trace("...");

    // ??
    int pageNum = pageParams.getPageIndex();
    int pageSize = pageParams.getPageSize();
    if (pageSize > 100) {
        LOGGER.warn(", ?[{}] ?, ? 100 ?", pageSize);
        pageSize = 100;
    }

    // ?
    PageHelper.startPage(pageNum, pageSize);

    Example example = new Example(entityClass);
    // ??
    E params = pageParams.getParamEntity();
    if (params != null) {
        Example.Criteria criteria = example.createCriteria();
        PropertyDescriptor[] propArray = BeanUtils.getPropertyDescriptors(entityClass);
        for (PropertyDescriptor pd : propArray) {
            if (pd.getPropertyType().equals(Class.class)) {
                continue;
            }
            try {
                Object value = pd.getReadMethod().invoke(params);
                if (value != null) {
                    if (pd.getPropertyType() == String.class) {
                        String strValue = (String) value;
                        if (strValue.startsWith("%") || strValue.endsWith("%")) {
                            criteria.andLike(pd.getName(), strValue);
                            continue;
                        }
                    }
                    criteria.andEqualTo(pd.getName(), value);
                }
            } catch (IllegalAccessException | InvocationTargetException e) {
                LOGGER.error("example: {}", e.getMessage(), e);
            }
        }
    }
    // ??
    String orderBy = pageParams.getOrderBy();
    if (StringUtils.hasText(orderBy)) {
        processOrder(example, orderBy, pageParams.isAsc());
    }
    List<E> results = baseMapper.selectByExample(example);

    // 
    if (results == null || !(results instanceof Page)) {
        return new PageResults<>(0, new ArrayList<E>(0), pageParams);
    }
    Page page = (Page) results;
    Long totalCount = page.getTotal();
    return new PageResults<>(totalCount.intValue(), Collections.unmodifiableList(results), pageParams);
}

From source file:net.mojodna.searchable.AbstractBeanIndexer.java

/**
 * Add sortable fields.//from   www.ja v a 2  s . co m
 * 
 * @param doc Document to add fields to.
 * @param bean Bean to process.
 * @param descriptor Property descriptor.
 * @param stack Stack containing parent field names.
 * @return Document with additional fields.
 * @throws IndexingException
 */
protected Document addSortableFields(final Document doc, final Searchable bean,
        final PropertyDescriptor descriptor, final Stack<String> stack) throws IndexingException {
    final Method readMethod = descriptor.getReadMethod();
    if (null != readMethod && AnnotationUtils.isAnnotationPresent(readMethod, Sortable.class)) {

        // don't index elements marked as nested=false in a nested context
        if (!stack.isEmpty() && !isNestedSortable(descriptor)) {
            return doc;
        }

        for (final String fieldname : SearchableUtils.getFieldnames(descriptor)) {
            log.debug("Indexing " + descriptor.getName() + " as sortable (" + getFieldname(fieldname, stack)
                    + ").");

            try {
                final Object prop = PropertyUtils.getProperty(bean, descriptor.getName());
                if (null == prop)
                    return doc;

                if (prop instanceof Date) {
                    // handle Dates specially
                    // TODO specify resolution
                    doc.add(new Field(SORTABLE_PREFIX + getFieldname(fieldname, stack),
                            DateTools.dateToString((Date) prop, DateTools.Resolution.SECOND), Field.Store.YES,
                            Field.Index.UN_TOKENIZED));
                } else if (!(prop instanceof Searchable)) {
                    final String value = prop.toString();
                    doc.add(new Field(SORTABLE_PREFIX + getFieldname(fieldname, stack), value, Field.Store.YES,
                            Field.Index.UN_TOKENIZED));
                }
            } catch (final Exception e) {
                throw new IndexingException("Unable to index bean.", e);
            }
        }
    }

    return doc;
}