1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.intercept.web;
17
18 import java.beans.PropertyEditorSupport;
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.StringReader;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.acegisecurity.util.StringSplitUtils;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.springframework.util.StringUtils;
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class FilterInvocationDefinitionSourceEditor extends PropertyEditorSupport {
43
44
45 private static final Log logger = LogFactory.getLog(FilterInvocationDefinitionSourceEditor.class);
46 public static final String DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON =
47 "CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON";
48 public static final String DIRECTIVE_PATTERN_TYPE_APACHE_ANT = "PATTERN_TYPE_APACHE_ANT";
49
50
51
52 public void setAsText(String s) throws IllegalArgumentException {
53 FilterInvocationDefinitionDecorator source = new FilterInvocationDefinitionDecorator();
54
55 if ((s == null) || "".equals(s)) {
56
57 source.setDecorated(new RegExpBasedFilterInvocationDefinitionMap());
58 } else {
59
60 if (s.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) {
61 source.setDecorated(new PathBasedFilterInvocationDefinitionMap());
62
63 if (logger.isDebugEnabled()) {
64 logger.debug(("Detected " + DIRECTIVE_PATTERN_TYPE_APACHE_ANT
65 + " directive; using Apache Ant style path expressions"));
66 }
67 } else {
68 source.setDecorated(new RegExpBasedFilterInvocationDefinitionMap());
69 }
70
71 if (s.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) {
72 if (logger.isDebugEnabled()) {
73 logger.debug("Detected " + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
74 + " directive; Instructing mapper to convert URLs to lowercase before comparison");
75 }
76
77 source.setConvertUrlToLowercaseBeforeComparison(true);
78 }
79
80 BufferedReader br = new BufferedReader(new StringReader(s));
81 int counter = 0;
82 String line;
83
84 List mappings = new ArrayList();
85
86 while (true) {
87 counter++;
88
89 try {
90 line = br.readLine();
91 } catch (IOException ioe) {
92 throw new IllegalArgumentException(ioe.getMessage());
93 }
94
95 if (line == null) {
96 break;
97 }
98
99 line = line.trim();
100
101 if (logger.isDebugEnabled()) {
102 logger.debug("Line " + counter + ": " + line);
103 }
104
105 if (line.startsWith("//")) {
106 continue;
107 }
108
109
110 if (line.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1) {
111
112 if ((line.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) || (line.lastIndexOf("=") != -1)) {
113 throw new IllegalArgumentException("Line appears to be malformed: " + line);
114 }
115 }
116
117
118 if (line.lastIndexOf(DIRECTIVE_PATTERN_TYPE_APACHE_ANT) != -1) {
119
120 if ((line.lastIndexOf(DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON) != -1)
121 || (line.lastIndexOf("=") != -1)) {
122 throw new IllegalArgumentException("Line appears to be malformed: " + line);
123 }
124 }
125
126
127 if (line.lastIndexOf('=') == -1) {
128 continue;
129 }
130
131 if (line.lastIndexOf("==") != -1) {
132 throw new IllegalArgumentException("Only single equals should be used in line " + line);
133 }
134
135
136
137 String name = StringSplitUtils.substringBeforeLast(line, "=");
138 String value = StringSplitUtils.substringAfterLast(line, "=");
139
140 if (!StringUtils.hasText(name) || !StringUtils.hasText(value)) {
141 throw new IllegalArgumentException("Failed to parse a valid name/value pair from " + line);
142 }
143
144
145 if (source.isConvertUrlToLowercaseBeforeComparison()
146 && source.getDecorated() instanceof PathBasedFilterInvocationDefinitionMap) {
147
148
149 for (int i = 0; i < name.length(); i++) {
150 String character = name.substring(i, i + 1);
151
152 if (!character.toLowerCase().equals(character)) {
153 throw new IllegalArgumentException("You are using the "
154 + DIRECTIVE_CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
155 + " with Ant Paths, yet you have specified an uppercase character in line: " + line
156 + " (character '" + character + "')");
157 }
158 }
159 }
160
161 FilterInvocationDefinitionSourceMapping mapping = new FilterInvocationDefinitionSourceMapping();
162 mapping.setUrl(name);
163
164 String[] tokens = org.springframework.util.StringUtils
165 .commaDelimitedListToStringArray(value);
166
167 for (int i = 0; i < tokens.length; i++) {
168 mapping.addConfigAttribute(tokens[i].trim());
169 }
170
171 mappings.add(mapping);
172 }
173 source.setMappings(mappings);
174 }
175
176 setValue(source.getDecorated());
177 }
178 }