SeamFramework.orgCommunity Documentation
Properties are a convenient way of locating and working with JavaBean properties. They can be used with properties exposed via a getter/setter method, or directly via the field of a bean, providing a uniform interface that allows you all properties in the same way.
Property queries allow you to interrogate a class for properties which match certain criteria.
The Property<V>
interface declares a number of methods for interacting with bean properties.
You can use these methods to read or set the property value, and read the property type information. Properties
may be readonly.
Table 10.1. Property methods
Method |
Description | |
---|---|---|
|
Returns the name of the property. | |
|
Returns the property type. | |
|
Returns the property class. | |
|
Returns the annotated element -either the | |
|
Returns the value of the property. | |
|
Sets the value of the property. | |
|
Gets the class declaring the property. | |
|
Check if the property can be written as well as read. |
Given a class with two properties, personName
and postcode
:'
class Person {
PersonName personName;
Address address;
void setPostcode(String postcode) {
address.setPostcode(postcode);
}
String getPostcode() {
return address.getPostcode();
}
}
You can create two properties:
Property<PersonName> personNameProperty = Properties.createProperty(Person.class.getField("personName");
Property<String> postcodeProperty = Properties.createProperty(Person.class.getMethod("getPostcode"));
To create a property query, use the PropertyQueries
class to create a new
PropertyQuery
instance:
PropertyQuery<?> query = PropertyQueries.createQuery(Foo.class);
If you know the type of the property that you are querying for, you can specify it via a type parameter:
PropertyQuery<String> query = PropertyQueries.<String>createQuery(identityClass);
Once you have created the PropertyQuery
instance, you can add search criteria. Weld Extensions
provides three built-in criteria types, and it is very easy to add your own. A criteria is added to a query via the
addCriteria()
method. This method returns an instance of the PropertyQuery
,
so multiple addCriteria()
invocations can be stacked.
This criteria is used to locate bean properties that are annotated with a certain annotation type. For example, take the following class:
public class Foo { private String accountNumber; private @Scrambled String accountPassword; private String accountName; }
To query for properties of this bean annotated with @Scrambled
, you can use an
AnnotatedPropertyCriteria
, like so:
PropertyQuery<String> query = PropertyQueries.<String>createQuery(Foo.class) .addCriteria(new AnnotatedPropertyCriteria(Scrambled.class));
This query matches the accountPassword
property of the Foo
bean.
This criteria is used to locate a bean property with a particular name. Take the following class:
public class Foo { public String getBar() { return "foobar"; } }
The following query will locate properties with a name of "bar"
:
PropertyQuery<String> query = PropertyQueries.<String>createQuery(Foo.class) .addCriteria(new NamedPropertyCriteria("bar"));
This criteria can be used to locate bean properties with a particular type.
public class Foo { private Bar bar; }
The following query will locate properties with a type of Bar
:
PropertyQuery<Bar> query = PropertyQueries.<Bar>createQuery(Foo.class) .addCriteria(new TypedPropertyCriteria(Bar.class));
To create your own property criteria, simply implement the
org.jboss.weld.extensions.util.properties.query.PropertyCriteria
interface, which declares the
two methods fieldMatches()
and methodMatches
. In the following example, our
custom criteria implementation can be used to locate whole number properties:
public class WholeNumberPropertyCriteria implements PropertyCriteria { public boolean fieldMatches(Field f) { return f.getType() == Integer.class || f.getType() == Integer.TYPE.class || f.getType() == Long.class || f.getType() == Long.TYPE.class || f.getType() == BigInteger.class; } boolean methodMatches(Method m) { return m.getReturnType() == Integer.class || m.getReturnType() == Integer.TYPE.class || m.getReturnType() == Long.class || m.getReturnType() == Long.TYPE.class || m.getReturnType() == BigInteger.class; } }
After creating the PropertyQuery
and setting the criteria, the query can be executed by invoking
either the getResultList()
or getFirstResult()
methods. The
getResultList()
method returns a List
of Property
objects,
one for each matching property found that matches all the specified criteria:
List<Property<String>> results = PropertyQueries.<String>createQuery(Foo.class) .addCriteria(TypedPropertyCriteria(String.class)) .getResultList();
If no matching properties are found, getResultList()
will return an empty List
.
If you know that the query will return exactly one result, you can use the getFirstResult()
method
instead:
Property<String> result = PropertyQueries.<String>createQuery(Foo.class) .addCriteria(NamedPropertyCriteria("bar")) .getFirstResult();
If no properties are found, then getFirstResult()
will return null. Alternatively, if more than one
result is found, then getFirstResult()
will return the first property found.