All the patterns to this point have matched based on class and package names. With version 0.4, Macker supports matching on other features of a class using filters. Any pattern tag -- any tag which supports the class
and pattern
attributes -- also supports the filter
attribute:
<pattern-tag filter="filter-name" ...options... />
This simple example uses the filter named "interface" to create a pattern which matches all interfaces:
<pattern name="all-interface" filter="interface" />
You can combine patterns based on filters, just as you would combine any other sort of pattern:
<pattern name="concrete-class"> <exclude filter="interface"> <exclude filter="abstract-class"> </pattern>
Some filters take a pattern as a parameter. In this case, the filter expects a class
or pattern
attribute, which becomes the parameter to the filter. In this example, java.util.List
is a parameter to subtype-of
:
<pattern name="list" filter="subtype-of" class="java.util.List" />
Nested elements are not a parameter to the filter -- they behave the same as ever. This means that you'll sometimes need to declare a named helper pattern to build up the pattern you want. For example, this pattern would not be possible without the definition of the pattern named all-interface
above:
<pattern name="concrete-iface-impl" filter="subtype-of" pattern="all-interface" /> <include pattern="concrete-class" /> </pattern>
Admittedly, this is a small set. It will grow with future versions of Macker.
Filter | Description |
---|---|
primary-class | Matches primary classes (those passed as input to Macker) |
primitive-type | Matches any of the nine Java primitive types (including void). |
interface | Matches interfaces, as the name implies. |
abstract-class | Matches abstract classes (but not interfaces). |
final-class | Matches classes declared final. Exciting, isn't this? |
class-access | Matches based on the access (visibility) of the class itself. This does not take into account the visibility of any of the methods -- that's for a future filter.
This filter expects the attributes min and/or max . Each may be one of:
Examples:
|
subtype-of | Matches based on which other classes the given class is assignable from. This includes anything it extends or implements, directly or indirectly, and the class itself. I'll repeat that last bit, because it will catch you off guard: a class is considered a subtype of itself.
Examples:
|
Filters are not limited to the standard set above; filters are intended for extensibility. However, I'm not going to document how to write your own filters here, for several incredibly good reasons:
If you're dying to know, here's the gist of it. Please keep in mind that anything you write might hit some upgrade bumps until Macker 1.0 ... but please do experiment!
net.innig.macker.rule.filter.Filter
(see the source files in that package for examples).
net/innig/macker/filter.properties
in Macker's classpath with the line filter-name=com.whatever.MyFilterClass
. (Macker merges this with the standard filters, so you only need to declare your own.)
net/innig/macker/macker.dtd
in Macker's classpath ahead of macker.jar
. This is a hack; in the future, Macker will allow a filter to declare which options it takes, and not force you to override the DTD.