You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by foo bar <li...@gmail.com> on 2009/06/10 16:44:47 UTC

Regular Expression Action Mapper

Hi all,

I've just started implementing a regex action mapper (influenced by
Django's URL dispatcher [1]).
Just wondering whether anyone has done this before.
Would like to know what other people think as well.
Ideas ? Suggestions ? Bugs ?

This is what I have at the moment,

protected String[] urlPatternList = new String[]{
    "showRequest:id:^/request/(\\d+)$",
    "editNewRequest::^/request/new$",
    "editNewRequest:divisionId,groupId:^/request/(\\d{4})/(\\d{2})$",
    "searchArticle:articleId,groupId,divisionId:^/article/(\\d{4})/(\\d{2})/(\\d+)$"
};	
// obviously this will eventually be put in a text file somewhere
instead of a String[]

For request uri contextroot/request/74837
it will return a mapping with name showRequest, and parameter id set to 74837

For request uri contextroot/article/4389/43/8934839
it will return a mapping with name searchArticle and parameter
articleId set to 4389,
groupdId to 34, and so on

I'm still not quite sure what the other two methods are used for/get called when

ActionMapping getMappingFromActionName(String actionName);
String getUriFromActionMapping(ActionMapping mapping);
I believe getUriFromActionMapping() is some sort of the reverse of
getMapping(),
gets called when struts2 want to render struts2 tags.
Does this mean for mapping.name = editNewRequest, mapping.params = {
divisionId:8549, groupId:77 } it will need to return uri =
/request/8549/77 ?
Not sure how to do this just by using my urlPatternList, replace each
parenthesis in the regex pattern with param values ?

Any suggestions/ideas are welcomed.

Possible improvements,
1. Possibility of specifying a method name, ie. request!show:id:regex-pattern
which means to execute show() in request Action
2. Possibility to match GET/POST/PUT ? Do we need this ?
3. Is the url pattern syntax flexible enough ?
4. Namespaces ? are they relevant in this case ?

[1] http://docs.djangoproject.com/en/dev/topics/http/urls/

-- start code --

public class RegexActionMapper extends DefaultActionMapper {
	
	protected String[] urlPatternList = new String[]{
		"viewRequest:id:^/request/view/(\\d+)$",
		"editNewRequest::^/request/new$",
		"viewRequest:request.id:^/request/(\\d+)$",
		"searchArticle:articleId,groupId,divisionId:^/article/(\\d{4})/(\\d{2})/(\\d+)$"
	};	
		
	protected Pattern[] patternList = new Pattern[0];
	protected Map<Pattern, String> actionNameMap = new HashMap<Pattern, String>();
	protected Map<Pattern, String[]> parameterMap = new HashMap<Pattern,
String[]>();
	
	public RegexActionMapper() {
		
		String actionName;
		String[] params;
		String pattern;
		String[] fields;
		Map<String, String> parameters;
		
		patternList = new Pattern[urlPatternList.length];
		for (int i=0;i<urlPatternList.length;i++) {
			
			fields = urlPatternList[i].split(":");
			
			actionName = fields[0];
			params = fields[1].split(",");
			pattern = fields[2];
			
			patternList[i] = Pattern.compile(pattern);
			actionNameMap.put(patternList[i], actionName);			
			parameterMap.put(patternList[i], params);
			
		}
		System.out.println(">> " + this.getClass().getSimpleName() + " initialised");
	}

	public ActionMapping getMapping(HttpServletRequest request,
ConfigurationManager configManager) {
        ActionMapping mapping = new ActionMapping();
        String uri = getUri(request);

        Map params;
        int i;
        boolean matchFound = false;

        Matcher matcher;
        for (Pattern pattern : patternList) {
        	if ((matcher = pattern.matcher(uri)).matches()) {
        		System.out.println(">> " + uri + " matches " + pattern.toString());
        		        		
        		mapping.setExtension("");
        		mapping.setNamespace("/");
        		mapping.setName(actionNameMap.get(pattern));
        		mapping.setParams(new HashMap());
        		
        		for (i=1;i<=matcher.groupCount();i++) {
        			mapping.getParams().put(parameterMap.get(pattern)[i-1], new
String[]{matcher.group(i)});
        		}
        		matchFound = true;
        		break;
        	}
        }

        if (!matchFound) {
        	 mapping = super.getMapping(request, configManager);
        }

        return mapping;
	}

}	

-- end code --

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org