Macker Guide

Naming and Combining Patterns

Naming Patterns

To eliminate redundancy, or simply for the sake of conceptual clarity and readability, you can give patterns names using the <pattern> tag. Access rules (see next section) and other patterns can then refer to the pattern by name.

<pattern name="pattern-name" class="macker-class" />

Here are a few patterns one might define:

<pattern name="java-api" class="java*.**" />
<pattern name="exception" class="**Exception" />
<pattern name="ui-layer" class="com.foobar.whatsitproject.ui.**" />

A pattern definition sits inside a <ruleset> or <foreach> (explained in a later section) tag. The definition is valid until the end of that tag, and applies to child rulesets. This means that you can combine different rulesets in the same rules file without worrying about name conflicts.

<macker>
    <ruleset>
        <!-- This pattern definition applies to both rulesets below -->
        <pattern name="java-sql" class="java*.sql.**" />

        <ruleset>
                <pattern name="ui" class="com.foobar.whatsitproject.ui.**" />
                <pattern name="db" class="com.foobar.whatsitproject.db.**" />
                <!-- Whatsitproject rules go here -->
        </rulset>

        <ruleset>
                <pattern name="db" class="com.foobar.util.db.**" />
                <!-- General DB util rules go here -->
        </rulset>
    </rulset>
</macker>

Occasionally, you'll want to make one pattern simply an alias for another. Use this syntax:

<pattern name="alias-name" pattern="original-pattern-name" />

Include / Exclude

Macker's regular expressions are rather limited; the real power of its pattern matching comes from its ability to combine patterns with the <include> and <exclude> tags. These tags successively add and remove patterns to build up a set of matching classes. A single include/exclude tag can specify either a regular expression, or the name of a previously declared pattern:

<include class="expression" />
<exclude class="expression" />
<include pattern="pattern-name" />
<exclude pattern="pattern-name" />

When you list includes and excludes inside a pattern definition, Macker will apply each in turn to see if a class matches. This pattern, for example, matches the Java APIs which are not automatically imported:

<pattern name="java-api-noautoimport">
    <include class="java.**" />
    <exclude class="java.lang.*" />
</pattern>

One could also define this pattern incrementally -- first, all Java APIs, then those which are auto-imported, then those which are not:

<pattern name="java-api" class="java.**" />
<pattern name="java-api-autoimport" class="java.lang.*" />
<pattern name="java-api-noautoimport">
    <include pattern=java-api" />
    <exclude pattern="java-api-autoimport" />
</pattern>

When the first item in the list is an include, everything starts out excluded; conversely, when the first item is an exclude, everything starts out included. You thus negate a pattern as follows:

<pattern name="not-java-api">
    <exclude pattern=java-api"" />
</pattern>

Note that the order of includes and excludes within a list is important -- Macker applies them in the sequence you list them.

Nesting

You can place an include/exclude list inside another include or exclude tag. When you do this, Macker will apply the nested rules only when the outer one applied.

<pattern name="java2-collections">
    <include class="java.util.*">
        <include class="**Collection*" />
        <include class="**List*" />
        <include class="**Map**" />
        <include class="**Set*">
            <exclude class="**.BitSet" />
        </include>
        <include class="**Array*" />
        <include class="**.Iterator" />
    </include>
</pattern>

Sequential includes form a boolean OR; nested includes form a boolean AND.

<pattern name="A-or-B-or-C">
    <include pattern="A" />
    <include pattern="B" />
    <include pattern="C" />
</pattern>

<pattern name="A-and-B-and-C">
    <include pattern="A">
        <include pattern="B">
            <include pattern="C" />
        </include>
    </include>
</pattern>

You can specify both a class / pattern attribute on a <pattern> tag, and nested include/exclude rules. When you do this, the outer <pattern> behaves like an outer <include> element. We can thus slightly simplify one of the patterns above:

<pattern name="java-api-noautoimport" pattern=java-api">
    <exclude pattern="java-api-autoimport" />
</pattern>

"All this pattern stuff is very nice", you may ask, "but what can one do with it?"

SourceForge Logo        innig