Final classes and a regexp agent decoratormapper

time4tea <[email protected]> Fri, 20 May 2005 15:26:26 CDT
Newsgroups gmane.comp.web.sitemesh.general
Message-ID <704215.1116620816602.JavaMail.os-j2ee@opensymphony01.contegix.com>
Just a small niggle in a a great piece of software.... why make classes final and so difficult to extend? Case in point, I wanted to make a RegexpDecoratorMapper, which would have involved subclassing AgentDecoratorMapper, and overriding getExt() and initMap(), however, the class was declared final, and in any case those methods were declared private.

In such a "framework" as this, it would be great if we can extend such good example classes as these (even with the caveat that the class API might not be 100% stable, its still better than a copy 'n' paste job).

Anyhow, if anybody finds it interesting or vaguely useful:

/*
 * Copyright (c) 2005 Gill Flett Lifestyle Photography . All Rights Reserved.
 * $Header: /data/cvsroot/wedding_maven/Wedding.ipr,v 1.1.1.1 2005/04/23 20:17:26 richja Exp $
 */
package com.gillflett.lifestyle.jsp.sitemesh;

import com.opensymphony.module.sitemesh.Config;
import com.opensymphony.module.sitemesh.Decorator;
import com.opensymphony.module.sitemesh.DecoratorMapper;
import com.opensymphony.module.sitemesh.Page;
import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
import com.opensymphony.module.sitemesh.mapper.DefaultDecorator;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * Extend the idea of the AgentDecoratorMapper to use a regexp to match stuff.
 * <p/>
 * $Header$
 * Initially by: james on 20-May-2005
 */
public class AgentRegexpDecoratorMapper extends AbstractDecoratorMapper {

    protected Map<Pattern, String> map;

    public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
        super.init(config, properties, parent);
        map = new HashMap<Pattern, String>();
        initMap(properties);
    }

    public Decorator getDecorator(HttpServletRequest request, Page page) {
        try {
            Decorator result = null;
            final Decorator d = super.getDecorator(request, page);
            String path = modifyPath(d.getPage(), getExt(request.getHeader("User-Agent")));

            File decFile = new File(config.getServletContext().getRealPath(path));

            if (decFile.isFile()) {
                result = new DefaultDecorator(d.getName(), path, null) {
                    public String getInitParameter(String paramName) {
                        return d.getInitParameter(paramName);
                    }
                };
            }
            return result == null ? super.getDecorator(request, page) : result;
        }
        catch (NullPointerException e) {
            return super.getDecorator(request, page);
        }
    }

    /**
     * Get extension for user-agent.
     */
    protected String getExt(String userAgent) {

        Perl5Matcher matcher = new Perl5Matcher();

        for (Map.Entry<Pattern, String> entry : map.entrySet()) {
            Pattern pattern = entry.getKey();
            if (matcher.contains(userAgent, pattern)) {
                return entry.getValue();
            }
        }
        return null;
    }

    /**
     * Change /abc/def.jsp into /abc/def-XYZ.jsp
     */
    protected static String modifyPath(String path, String ext) {
        int dot = path.indexOf('.');
        if (dot > -1) {
            return path.substring(0, dot) + '-' + ext + path.substring(dot);
        }
        else {
            return path + '-' + ext;
        }
    }

    /**
     * Initialize user-agent mappings.
     */
    protected void initMap(Properties props) {
        Iterator i = props.entrySet().iterator();
        Perl5Compiler compiler = new Perl5Compiler();
        while (i.hasNext()) {
            Map.Entry entry = (Map.Entry) i.next();

            String key = (String) entry.getKey();
            if (key.startsWith("match.")) {
                String match = key.substring(6);
                try {
                    Pattern pattern = compiler.compile(match);
                    String ext = (String) entry.getValue();
                    map.put(pattern, ext);
                }
                catch (MalformedPatternException e) {
                    //Log.error(this, "", "initMap", "Malformed regexp " + match + ":" + e.toString());
                }
            }
        }
    }
}

---------------------------------------------------------------------
Posted via Jive Forums
http://forums.opensymphony.com/thread.jspa?threadID=2422&messageID=6976#6976


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]