I had a lot of similar pipelines being different only in the generator stage.
So I've created a custom selector, that reports if a file with the given extension exists in the configured path.
Here is its source code (quite simple):
Source code
{{{package es.fcc.cocoon;
import java.io.File; import java.util.Map;
import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.parameters.ParameterException; import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.selection.Selector;
public class ExtensionSelector extends AbstractLogEnabled implements Selector {
/** @see org.apache.cocoon.selection.Selector#select(java.lang.String, java.util.Map, org.apache.avalon.framework.parameters.Parameters) */ public boolean select(String expression, Map objectModel, Parameters parameters) {
- String path = parameters.getParameter("path", null); if (path == null) {
- getLogger().warn("Unspecified path parameter"); return false;
path = ObjectModelHelper.getContext(objectModel).getRealPath("/")+path+"."+expression; if (getLogger().isDebugEnabled()) {
- getLogger().debug("Looking for the existence of "+path);
- String path = parameters.getParameter("path", null); if (path == null) {
} }}}
Declaration
Here is how the component is declared in the sitemap:
<map:selector name="extension"src="es.fcc.cocoon.ExtensionSelector"/>
Pipeline usage
And finally how it is used in a pipeline:
<map:match pattern="**/*.frm">
<map:select type="extension">
<!--Tell our custom action the path where to search in-->
<map:parameter name="path" value="{1}/{2}"/>
<map:when test="xsp">
<!--Map xsp extension to serverpages generator-->
<map:generate type="serverpages" src="{1}/{2}.xsp"/>
</map:when>
<map:when test="xml">
<!--Map xml extension to default file generator-->
<map:generate src="{1}/{2}.xml"/>
</map:when>
<map:otherwise>
<!--Unknown generator-->
</map:otherwise>
</map:select>
</map:select>
<!--The pipeline processing continues here-->
</map:match>In this way we can change the type the generator by simply changing the source filename extension and without bothering updating the sitemap, and uniformizing complicated pipelines and sub-pipelines.
Comments are welcome!
Comment: Good idea, not that good implementation. Issues are:
Use of get!RealPath(). This method must be avoided at all costs
Will not work in sub-sitemaps (because of get!RealPath('/'))
- Will not work in WAR, EAR files (because of File)
See ResourceExistsAction for an inspiration for better implementation. --Vadim