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[] specialNames = 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 WebUtils.ERROR_STATUS_CODE_ATTRIBUTE,
63 WebUtils.ERROR_EXCEPTION_TYPE_ATTRIBUTE,
64 WebUtils.ERROR_MESSAGE_ATTRIBUTE,
65 WebUtils.ERROR_EXCEPTION_ATTRIBUTE,
66 WebUtils.ERROR_REQUEST_URI_ATTRIBUTE,
67 WebUtils.ERROR_SERVLET_NAME_ATTRIBUTE
68 };
69
70 private final Object[] localValues = new Object[specialNames.length];
71 private final Object[] originalValues = new Object[specialNames.length];
72
73 public SpecialAttributeRequestWrapper(HttpServletRequest request) {
74 super(request);
75 }
76
77 public boolean setSpecialAttribute(String name, Object value) {
78 for (int i = 0; i < specialNames.length; i++) {
79 if (name.equals(specialNames[i])) {
80 localValues[i] = value;
81 originalValues[i] = super.getAttribute(name);
82 return true;
83 }
84 }
85 return false;
86 }
87
88 @Override
89 public Object getAttribute(String name) {
90 for (int i = 0; i < specialNames.length; i++) {
91 if (specialNames[i].equals(name) && localValues[i] != null) {
92 if (shouldMasquerade(name)) {
93 return localValues[i];
94 } else {
95 break;
96 }
97 }
98 }
99 return super.getAttribute(name);
100 }
101
102 protected boolean shouldMasquerade(String name) {
103 for (int i = 0; i < specialNames.length; i++) {
104 if (localValues[i] != null && !ObjectUtils.equals(super.getAttribute(specialNames[i]), originalValues[i])) {
105 return false;
106 }
107 }
108 return true;
109 }
110
111 @Override
112 public Enumeration getAttributeNames() {
113
114 return new Enumeration() {
115
116 private int pos = 0;
117 private String next = null;
118 private Enumeration parentEnumeration = getRequest().getAttributeNames();
119
120 @Override
121 public boolean hasMoreElements() {
122 while (pos < localValues.length) {
123 if (localValues[pos] != null) {
124 return true;
125 }
126 pos++;
127 }
128 if (next != null) {
129 return true;
130 }
131 next = findNext();
132 return next != null;
133 }
134
135 @Override
136 public Object nextElement() {
137 while (pos < localValues.length) {
138 if (localValues[pos] != null) {
139 String name = specialNames[pos];
140 pos++;
141 return name;
142 }
143 pos++;
144 }
145 if (next == null) {
146 next = findNext();
147 if (next == null) {
148 throw new NoSuchElementException();
149 }
150 }
151 Object result = next;
152 next = null;
153 return result;
154 }
155
156 private String findNext() {
157 while (parentEnumeration.hasMoreElements()) {
158 String name = (String) parentEnumeration.nextElement();
159 if (!hasLocalValue(name)) {
160 return name;
161 }
162 }
163 return null;
164 }
165 };
166 }
167
168 @Override
169 public void setAttribute(String name, Object o) {
170 if (!hasLocalValue(name)) {
171 super.setAttribute(name, o);
172 }
173 }
174
175 @Override
176 public void removeAttribute(String name) {
177 if (!hasLocalValue(name)) {
178 super.removeAttribute(name);
179 }
180 }
181
182 private boolean hasLocalValue(String name) {
183 for (int i = 0; i < specialNames.length; i++) {
184 if (name.equals(specialNames[i]) && localValues[i] != null) {
185 return true;
186 }
187 }
188 return false;
189 }
190 }