1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.blossom.support;
35
36 import java.util.Enumeration;
37 import java.util.NoSuchElementException;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletRequestWrapper;
40
41 import org.apache.commons.lang.ObjectUtils;
42 import org.springframework.web.util.WebUtils;
43
44
45
46
47
48
49 public class SpecialAttributeRequestWrapper extends HttpServletRequestWrapper {
50
51 private static final String[] SPECIAL_ATTRIBUTE_NAMES = new String[]{
52 WebUtils.INCLUDE_REQUEST_URI_ATTRIBUTE,
53 WebUtils.INCLUDE_CONTEXT_PATH_ATTRIBUTE,
54 WebUtils.INCLUDE_SERVLET_PATH_ATTRIBUTE,
55 WebUtils.INCLUDE_PATH_INFO_ATTRIBUTE,
56 WebUtils.INCLUDE_QUERY_STRING_ATTRIBUTE,
57 WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE,
58 WebUtils.FORWARD_CONTEXT_PATH_ATTRIBUTE,
59 WebUtils.FORWARD_SERVLET_PATH_ATTRIBUTE,
60 WebUtils.FORWARD_PATH_INFO_ATTRIBUTE,
61 WebUtils.FORWARD_QUERY_STRING_ATTRIBUTE
62
63
64
65
66
67
68 };
69
70 private final Object[] localValues = new Object[SPECIAL_ATTRIBUTE_NAMES.length];
71 private final Object[] originalValues = new Object[SPECIAL_ATTRIBUTE_NAMES.length];
72 private boolean enabled = true;
73
74 public SpecialAttributeRequestWrapper(HttpServletRequest request) {
75 super(request);
76 }
77
78 public boolean isEnabled() {
79 return enabled;
80 }
81
82 public void setEnabled(boolean enabled) {
83 this.enabled = enabled;
84 }
85
86 public boolean setSpecialAttribute(String name, Object value) {
87 for (int i = 0; i < SPECIAL_ATTRIBUTE_NAMES.length; i++) {
88 if (name.equals(SPECIAL_ATTRIBUTE_NAMES[i])) {
89 localValues[i] = value;
90 originalValues[i] = super.getAttribute(name);
91 return true;
92 }
93 }
94 return false;
95 }
96
97 @Override
98 public Object getAttribute(String name) {
99 if (enabled) {
100 for (int i = 0; i < SPECIAL_ATTRIBUTE_NAMES.length; i++) {
101 if (localValues[i] != null && SPECIAL_ATTRIBUTE_NAMES[i].equals(name)) {
102 if (shouldMasquerade(name)) {
103 return localValues[i];
104 } else {
105 break;
106 }
107 }
108 }
109 }
110 return super.getAttribute(name);
111 }
112
113 protected boolean shouldMasquerade(String name) {
114 for (int i = 0; i < SPECIAL_ATTRIBUTE_NAMES.length; i++) {
115 if (localValues[i] != null && !ObjectUtils.equals(super.getAttribute(SPECIAL_ATTRIBUTE_NAMES[i]), originalValues[i])) {
116 return false;
117 }
118 }
119 return true;
120 }
121
122 @Override
123 public Enumeration getAttributeNames() {
124
125 return new Enumeration() {
126
127 private int pos = 0;
128 private String next = null;
129 private Enumeration parentEnumeration = getRequest().getAttributeNames();
130
131 @Override
132 public boolean hasMoreElements() {
133 if (enabled) {
134 while (pos < localValues.length) {
135 if (localValues[pos] != null) {
136 return true;
137 }
138 pos++;
139 }
140 }
141 if (next != null) {
142 return true;
143 }
144 next = findNext();
145 return next != null;
146 }
147
148 @Override
149 public Object nextElement() {
150 if (enabled) {
151 while (pos < localValues.length) {
152 if (localValues[pos] != null) {
153 String name = SPECIAL_ATTRIBUTE_NAMES[pos];
154 pos++;
155 return name;
156 }
157 pos++;
158 }
159 }
160 if (next == null) {
161 next = findNext();
162 if (next == null) {
163 throw new NoSuchElementException();
164 }
165 }
166 Object result = next;
167 next = null;
168 return result;
169 }
170
171 private String findNext() {
172 while (parentEnumeration.hasMoreElements()) {
173 String name = (String) parentEnumeration.nextElement();
174 if (!enabled || !hasLocalValue(name)) {
175 return name;
176 }
177 }
178 return null;
179 }
180 };
181 }
182
183 @Override
184 public void setAttribute(String name, Object o) {
185 if (!hasLocalValue(name)) {
186 super.setAttribute(name, o);
187 }
188 }
189
190 @Override
191 public void removeAttribute(String name) {
192 if (!hasLocalValue(name)) {
193 super.removeAttribute(name);
194 }
195 }
196
197 private boolean hasLocalValue(String name) {
198 for (int i = 0; i < SPECIAL_ATTRIBUTE_NAMES.length; i++) {
199 if (localValues[i] != null && name.equals(SPECIAL_ATTRIBUTE_NAMES[i])) {
200 return true;
201 }
202 }
203 return false;
204 }
205 }