1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.intercept.web;
17
18 import org.acegisecurity.ConfigAttributeDefinition;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import org.apache.oro.text.regex.MalformedPatternException;
24 import org.apache.oro.text.regex.Pattern;
25 import org.apache.oro.text.regex.PatternMatcher;
26 import org.apache.oro.text.regex.Perl5Compiler;
27 import org.apache.oro.text.regex.Perl5Matcher;
28
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Set;
33 import java.util.Vector;
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class RegExpBasedFilterInvocationDefinitionMap extends AbstractFilterInvocationDefinitionSource
48 implements FilterInvocationDefinition {
49
50
51 private static final Log logger = LogFactory.getLog(RegExpBasedFilterInvocationDefinitionMap.class);
52
53
54
55 private List requestMap = new Vector();
56 private boolean convertUrlToLowercaseBeforeComparison = false;
57
58
59
60 public void addSecureUrl(String perl5RegExp, ConfigAttributeDefinition attr) {
61 Pattern compiledPattern;
62 Perl5Compiler compiler = new Perl5Compiler();
63
64 try {
65 compiledPattern = compiler.compile(perl5RegExp, Perl5Compiler.READ_ONLY_MASK);
66 } catch (MalformedPatternException mpe) {
67 throw new IllegalArgumentException("Malformed regular expression: " + perl5RegExp);
68 }
69
70 requestMap.add(new EntryHolder(compiledPattern, attr));
71
72 if (logger.isDebugEnabled()) {
73 logger.debug("Added regular expression: " + compiledPattern.getPattern().toString() + "; attributes: "
74 + attr);
75 }
76 }
77
78 public Iterator getConfigAttributeDefinitions() {
79 Set set = new HashSet();
80 Iterator iter = requestMap.iterator();
81
82 while (iter.hasNext()) {
83 EntryHolder entryHolder = (EntryHolder) iter.next();
84 set.add(entryHolder.getConfigAttributeDefinition());
85 }
86
87 return set.iterator();
88 }
89
90 public int getMapSize() {
91 return this.requestMap.size();
92 }
93
94 public boolean isConvertUrlToLowercaseBeforeComparison() {
95 return convertUrlToLowercaseBeforeComparison;
96 }
97
98 public ConfigAttributeDefinition lookupAttributes(String url) {
99 PatternMatcher matcher = new Perl5Matcher();
100
101 Iterator iter = requestMap.iterator();
102
103 if (isConvertUrlToLowercaseBeforeComparison()) {
104 url = url.toLowerCase();
105
106 if (logger.isDebugEnabled()) {
107 logger.debug("Converted URL to lowercase, from: '" + url + "'; to: '" + url + "'");
108 }
109 }
110
111 while (iter.hasNext()) {
112 EntryHolder entryHolder = (EntryHolder) iter.next();
113
114 boolean matched = matcher.matches(url, entryHolder.getCompiledPattern());
115
116 if (logger.isDebugEnabled()) {
117 logger.debug("Candidate is: '" + url + "'; pattern is " + entryHolder.getCompiledPattern().getPattern()
118 + "; matched=" + matched);
119 }
120
121 if (matched) {
122 return entryHolder.getConfigAttributeDefinition();
123 }
124 }
125
126 return null;
127 }
128
129 public void setConvertUrlToLowercaseBeforeComparison(boolean convertUrlToLowercaseBeforeComparison) {
130 this.convertUrlToLowercaseBeforeComparison = convertUrlToLowercaseBeforeComparison;
131 }
132
133
134
135 protected class EntryHolder {
136 private ConfigAttributeDefinition configAttributeDefinition;
137 private Pattern compiledPattern;
138
139 public EntryHolder(Pattern compiledPattern, ConfigAttributeDefinition attr) {
140 this.compiledPattern = compiledPattern;
141 this.configAttributeDefinition = attr;
142 }
143
144 protected EntryHolder() {
145 throw new IllegalArgumentException("Cannot use default constructor");
146 }
147
148 public Pattern getCompiledPattern() {
149 return compiledPattern;
150 }
151
152 public ConfigAttributeDefinition getConfigAttributeDefinition() {
153 return configAttributeDefinition;
154 }
155 }
156 }