One of the Components. Also one of the CocoonConditionals

Provides the means to associate a request with a pipeline. It uses aspects of the request URL, and the processing environment to do this. This information is tested against a match pattern, provided as a parameter to the matcher. If the match is successful the pipeline is selected.

Ordering of matchers is significant as the first available match is always used. Therefore ensure that specific tests are placed before generic tests, otherwise they will be shadowed.

The data tested against the match pattern is tokenized by the pattern. This means that these data elements are available within the subsequent pipeline processing. Parameters are numbered.


Matchers have to be registered in the Sitemap:

<map:matchers default="wildcard">
<map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcher"/>
<map:matcher name="regexp" src="org.apache.cocoon.matching.RegexpURIMatcher"/>

The default matcher is used if an alternate is not explicitly stated.


{{{<map:match pattern="jsp/*"> <map:generate type="jsp" src="/docs/samples/jsp/{1}.jsp"/> ... </map:match> <map:match pattern="hello.pdf"> </map:match> }}}

Matchers can be nested within one another: {{{<map:match pattern="foo/**">


Note that the full request URI is passed to nested matchers, so you need foo/*.html in the example above, rather than *.html. It may be worth mounting a sub-sitemap for foo in examples like this.

Available Implementations

There are several types of matchers:

Wildcard Matching Syntax

Regular Expression Matching Syntax

This is quite similar to the Wildcard Matching Syntax (see above), except that instead of asterisks ('*' and '**'), full-blown regular expression have to be used. Also, as the default matcher is wildcard, you have to explicitly set the type to regexp. To reuse submatches, you have to surround the regular expressions with parentheses. You can then refer to them by using the usual Cocoon conventions, i.e. '{N}'.

In the following example, three different URL patterns are matched by just one matcher (using the Wildcard Matcher, three different map:match sections would have to be used):

<map:match type="regexp" pattern="db/(.*)/(.*)/(toc|lot|lof)/(.*).xml">
  <map:read mime-type="text/xml" src="db/{1}/{2}/{3}/{4}.xml"/>

Matching on the existence of some information

Cocoon provides for this task the ParameterMatcher.

Here is a variation that allows a simpler use:

Sitemap declaration:

<map:matcher name="has-value" src="es.fcc.cocoon.HasValueMatcher"/>

Sample sitemap usage (tests if a sitemap variable called redirect exists):

<map:match pattern="{redirect}" type="has-value">
    <map:redirect-to uri="{1}"/>

As you can see, you specify the variable whose content is checked for not being empty directly in the pattern.

Its simple source code is shown here:

package es.fcc.cocoon;

import java.util.HashMap;
import java.util.Map;

import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.matching.Matcher;
import org.apache.cocoon.sitemap.PatternException;

public class HasValueMatcher implements Matcher {
        /** @see org.apache.cocoon.matching.Matcher#match(java.lang.String, java.util.Map, org.apache.avalon.framework.parameters.Parameters) */
        public Map match(String pattern, Map objectModel, Parameters parameters) throws PatternException {
                if (pattern == null || pattern.length() == 0) {
                        return null;
                Map map = new HashMap();
                map.put("1", pattern); 
                return map;

Note on nested matchers

If you have nested matchers you access the value of an outer matcher with a path like syntax : {../1}

Actions also count as nesting levels so if you wrap a pipeline in an action, you need to add another "../".

Example: {../../1}

Matcher (last edited 2009-09-20 23:40:27 by localhost)