1 24 package org.riotfamily.common.web.mapping; 25 26 import java.util.ArrayList ; 27 import java.util.Collection ; 28 import java.util.HashMap ; 29 import java.util.Map ; 30 import java.util.regex.Matcher ; 31 import java.util.regex.Pattern ; 32 33 import javax.servlet.http.HttpServletRequest ; 34 35 import org.riotfamily.common.util.FormatUtils; 36 import org.springframework.beans.PropertyAccessor; 37 import org.springframework.util.Assert; 38 import org.springframework.util.StringUtils; 39 40 public class AttributePattern { 41 42 public static final String EXPOSED_ATTRIBUTES = 43 AttributePattern.class.getName() + ".exposedAttributes"; 44 45 private static final Pattern ATTRIBUTE_NAME_PATTERN = 46 Pattern.compile("@\\{(.+?)((\\*)|\\:(.*?))?\\}"); 47 48 private static final Pattern STAR_PATTERN = 49 Pattern.compile("\\\\\\*"); 50 51 private static final Pattern DOUBLE_STAR_PATTERN = 52 Pattern.compile("\\\\\\*\\\\\\*"); 53 54 private String attributePattern; 55 56 private Pattern pattern; 57 58 private ArrayList attributeNames; 59 60 private ArrayList attributeTypes; 61 62 public AttributePattern(String attributePattern) { 63 this.attributePattern = attributePattern; 64 attributeNames = new ArrayList (); 65 attributeTypes = new ArrayList (); 66 Matcher m = ATTRIBUTE_NAME_PATTERN.matcher(attributePattern); 67 while (m.find()) { 68 attributeNames.add(m.group(1)); 69 attributeTypes.add(m.group(4)); 70 } 71 pattern = Pattern.compile(convertAttributePatternToRegex(attributePattern)); 72 } 73 74 public int getNumberOfWildcards() { 75 return attributeNames.size(); 76 } 77 78 private String convertAttributePatternToRegex(final String antPattern) { 80 String regex = FormatUtils.escapeChars(antPattern, "()", '\\'); regex = ATTRIBUTE_NAME_PATTERN.matcher(antPattern).replaceAll("(*$3)"); regex = "^" + FormatUtils.escapeChars(regex, ".+*?{^$", '\\') + "$"; regex = DOUBLE_STAR_PATTERN.matcher(regex).replaceAll(".*?"); regex = STAR_PATTERN.matcher(regex).replaceAll("[^/]*"); return regex; 86 } 87 88 public void expose(String urlPath, HttpServletRequest request) { 89 Map attributes = new HashMap (); 90 Matcher m = pattern.matcher(urlPath); 91 Assert.isTrue(m.matches()); 92 for (int i = 0; i < getNumberOfWildcards(); i++) { 93 String s = m.group(i + 1); 94 String type = (String ) attributeTypes.get(i); 95 String name = (String ) attributeNames.get(i); 96 Object value = convert(s, type); 97 request.setAttribute(name, value); 98 attributes.put(name, value); 99 } 100 request.setAttribute(EXPOSED_ATTRIBUTES, attributes); 101 } 102 103 private Object convert(String s, String type) { 104 if (type == null || type.equalsIgnoreCase("String")) { 105 return s; 106 } 107 if (type.equalsIgnoreCase("Integer")) { 108 return Integer.valueOf(s); 109 } 110 else if (type.equalsIgnoreCase("Long")) { 111 return Long.valueOf(s); 112 } 113 else if (type.equalsIgnoreCase("Short")) { 114 return Short.valueOf(s); 115 } 116 else if (type.equalsIgnoreCase("Double")) { 117 return Double.valueOf(s); 118 } 119 else if (type.equalsIgnoreCase("Float")) { 120 return Float.valueOf(s); 121 } 122 else if (type.equalsIgnoreCase("Boolean")) { 123 return Boolean.valueOf(s); 124 } 125 else if (type.equalsIgnoreCase("Character")) { 126 return new Character (s.charAt(0)); 127 } 128 else { 129 throw new IllegalArgumentException ("Unsupported type: " + type 130 + " - must be Integer, Long, Short, Double, Float," 131 + " Boolean or Character"); 132 } 133 } 134 public boolean matches(Map attributes) { 135 if (attributes != null) { 136 Collection names = attributes.keySet(); 137 return names.size() == getNumberOfWildcards() && 138 attributeNames.containsAll(names); 139 } 140 else { 141 return attributeNames.isEmpty(); 142 } 143 } 144 145 public String fillInAttributes(PropertyAccessor attributes) { 146 StringBuffer url = new StringBuffer (); 147 Matcher m = ATTRIBUTE_NAME_PATTERN.matcher(attributePattern); 148 while (m.find()) { 149 String name = m.group(1); 150 Object value = attributes.getPropertyValue(name); 151 if (value == null) { 152 return null; 153 } 154 String replacement = StringUtils.replace(value.toString(), "$", "\\$"); 155 m.appendReplacement(url, replacement); 156 } 157 m.appendTail(url); 158 return url.toString(); 159 } 160 161 public String fillInAttribute(Object value) { 162 Assert.state(getNumberOfWildcards() == 1, 163 "Pattern must contain exactly one wildcard."); 164 165 String replacement = StringUtils.replace(value.toString(), "$", "\\$"); 166 Matcher m = ATTRIBUTE_NAME_PATTERN.matcher(attributePattern); 167 return m.replaceFirst(replacement); 168 } 169 170 public String toString() { 171 return attributePattern; 172 } 173 174 public static String convertToAntPattern(String urlPattern) { 175 return ATTRIBUTE_NAME_PATTERN.matcher(urlPattern).replaceAll("*$3"); 176 } 177 178 } | Popular Tags |