I am looking for some feedback any may have on this: Let's say I've mounted a package "com.company.package" using PackageRequestTargetUrlCodingStrategy on "/foo." So I have several pages, /foo/Bar, /foo/Baz, etc. Now, I want my page mounts to be case-insensitive in the case that a user has caps lock on or types in all lower case or whatever. For PackageRequestTargetUrlCodingStrategy this works for the "/foo" part, but not the classname part, obviously.
So I implemented a CaseInsensitiveClassResolver that delegates to a DefaultClassResolver. In the case that the DefaultClassResolver cannot find the class, the CaseInsensitiveClassResolver tries to load the class by trying different combinations of upper/lower case in the classname. So, for "bar" it would try to resolve "com.company.package.Bar," " com.company.package.bAr," "com.company.package.baR," etc, obviously finding "com.company.package.Bar" and returning that class. This works pretty well. Now, obviously it's not the most efficient thing, possibly having to catch several ClassNotFoundException/NoClassDefFoundError exceptions before finding the class (assuming the name exists and is spelled correctly, just with wrong case). But it might be better than returning a 404 on a page simply due to improper case. I wouldn't expect it to happen often, as more often than not the user will probably use a link the get to the pages, and so no typing at all. But in the rare case... So, any thoughts? Here's the code: public class CaseInsensitiveClassResolver implements IClassResolver { private static final Logger logger = LoggerFactory.getLogger(CaseInsensitiveClassResolver.class); private DefaultClassResolver resolver = new DefaultClassResolver(); public Iterator<URL> getResources(String name) { return resolver.getResources(name); } public Class<?> resolveClass(String classname) { Class<?> clazz = null; try { clazz = resolver.resolveClass(classname); } catch (ClassNotFoundException e1) { clazz = resolveClassCaseInsensitive(classname); } catch (NoClassDefFoundError e2) { clazz = resolveClassCaseInsensitive(classname); } return clazz; } public Class<?> resolveClassCaseInsensitive(String classname) throws ClassNotFoundException { if (logger.isDebugEnabled()) { logger.debug("Class not found for " + classname + ". Trying to look up case-insensitive."); } String packageName = classname.substring(0, classname.lastIndexOf('.')); String simpleName = classname.substring(classname.lastIndexOf('.') + 1); String combos = capsCombinations(simpleName.toLowerCase(), 0); Class<?> cls = null; for (String combo : combos.split(",")) { try { cls = resolver.resolveClass(packageName + "." + combo); } catch (ClassNotFoundException e1) { if (logger.isDebugEnabled()) { logger.debug("Class not found for " + packageName + "." + combo + "."); } } catch (NoClassDefFoundError e2) { if (logger.isDebugEnabled()) { logger.debug("Class not found for " + packageName + "." + combo + "."); } } if (cls != null) { if (logger.isDebugEnabled()) { logger.debug("Class found for " + packageName + "." + combo + "."); } return cls; } } return null; } private String capsCombinations(String word, int startIndex) { StringBuilder sb = new StringBuilder(word); if (word.equals(word.toUpperCase())) { return sb.toString(); } else { for (; startIndex < word.length();) { char[] chars = word.toCharArray(); chars[startIndex] = Character.toUpperCase(chars[startIndex]); sb.append(","); sb.append(capsCombinations(new String(chars), ++startIndex)); } return sb.toString(); } } } -- Matthew Rollins Hanlon http://squareoftwo.org _____________________ Hanlon's Razor: "Never attribute to malice that which can be adequately explained by stupidity." http://wikipedia.org/wiki/Hanlon's_razor