Reviews
Oracle CoherenceOracle Coherence: Implementing Custom Value Extractor
While the built-in value extractors should be sufficient for most usage scenarios, there might be some situations where implementing a custom one makes sense. We have already implemented one custom value extractor, PropertyExtractor, in order to improve on the built-in ReflectionExtractor and allow ourselves to specify JavaBean property names instead of the full method names, but there are other scenarios when this might be appropriate.
One reason why you might want to implement a custom value extractor is to enable transformation of cache values from their native type to some other type. For example, most applications use UI controls such as drop-downs or list boxes to present a list of possible choices to the user. Let's assume that we need to display a list of countries in a drop-down on the registration screen for new customers.
We already have a cache containing all the countries, so we could easily get all the values from it and send them to the client, which would use them to populate the drop-down. However, the Country class we defined in Chapter 2 has a number of attributes we don't need in order to populate the drop-down list, such as capital, currency symbol, and currency name--the only attributes we do need are the country code and country name, so by sending any other information to the client we would only be wasting network bandwidth.
As a matter of fact, for most, if not all, drop-downs and list boxes in an application we will need only an identifier that will be returned as a selected value, and a description that should be used for display purposes. That means that we can define a class containing only those two attributes:
- public class LookupValue implements Serializable {
- private Object m_id
- private String m_description
- public LookupValue(Object id, String description) {
- m_id = id
- m_description = description
- }
- public Object getId() {
- return m_id
- }
- public String getDescription() {
- return m_description
- }
- }
Now that we have a holder class that can be used to represent any lookup value, the remaining question is how we can transform instances of the Country class into the instances of the LookupValue class. The answer is simple--we can write a custom value extractor that will do it for us:
- public class LookupValueExtractor
- extends AbstractExtractor
- implements PortableObject, Serializable {
- private ValueExtractor m_idExtractor
- private ValueExtractor m_descriptionExtractor
- public LookupValueExtractor(ValueExtractor idExtractor,
- ValueExtractor descriptionExtractor) {
- m_idExtractor = idExtractor
- m_descriptionExtractor = descriptionExtractor
- }
- public Object extractFromEntry(Map.Entry entry) {
- Object id = InvocableMapHelper.extractFromEntry(m_idExtractor,
- entry)
- String description = (String)
- InvocableMapHelper.extractFromEntry(m_descriptionExtractor, entry)
- return new LookupValue(id, description)
- }
- // equals and hashCode omitted for brevity
- }
The implementation is actually very simple: we allow users to specify two value extractors, an idExtractor and a descriptionExtractor, that we use to extract the values that are used to create a LookupValue instance. However, one thing deserves clarification.
Instead of simply implementing the ValueExtractor interface, we are extending the AbstractExtractor class and implementing the extractFromEntry method. The reason for this is that we want to be able to extract id and description not only from the entry value, but from the entry key as well.
In order to achieve that, we rely on the InvocableMapHelper class, which provides a utility method that can be used to extract a value from any object that implements Map.Entry interface.
Of course, the LookupValueExtractor is only part of the story--we still need a way to execute this extractor against all the objects in the countries cache and get the collection of extracted lookup values back. We will see what the best way to do that is shortly, but for now let's return to Coherence filters and see how we can make complex queries easier to create.
Oracle Coherence
- Oracle Coherence 3.5
- Oracle Coherence: Distributed Caching
- Oracle Coherence: In-place and Parallel Processing
- Oracle Coherence: Coherence within the Oracle Ecosystem
- Oracle Coherence: Querying The Data Grid
- Oracle Coherence: Built-in Filters
- Oracle Coherence: Value and Reflection Extractor
- Oracle Coherence: Other built-in value extractors
- Oracle Coherence: Implementing Custom Value Extractor
- Oracle Coherence: Simplifying Coherence Queries
- Oracle Coherence: Obtaining Query Results
- Oracle Coherence: Controlling Query Scope Using Data Affinity
- Oracle Coherence: Querying Near Cache
- Oracle Coherence: Paging Over Query Results
- Oracle Coherence: Anatomy of an Index
- Oracle Coherence: Creating Indexes
- Oracle Coherence: Query Limitations
- Oracle Coherence: Aggregators
- Oracle Coherence: Built-in Aggregators
- Oracle Coherence: Implementing LookupValuesAggregator







