001: /*
002: * Copyright (c) 2002-2007 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.interceptor;
006:
007: import java.util.Collections;
008: import java.util.LinkedHashMap;
009: import java.util.Map;
010: import java.util.Set;
011:
012: import javax.servlet.http.Cookie;
013: import javax.servlet.http.HttpServletRequest;
014:
015: import org.apache.commons.logging.Log;
016: import org.apache.commons.logging.LogFactory;
017:
018: import com.opensymphony.webwork.ServletActionContext;
019: import com.opensymphony.xwork.ActionContext;
020: import com.opensymphony.xwork.ActionInvocation;
021: import com.opensymphony.xwork.interceptor.AroundInterceptor;
022: import com.opensymphony.xwork.util.OgnlValueStack;
023: import com.opensymphony.xwork.util.TextParseUtil;
024:
025: /**
026: * <!-- START SNIPPET: description -->
027: *
028: * The aim of this interceptor is to set values in the stack/action based on cookie name/value
029: * of interest. <p/>
030: *
031: * If an asterik is present in cookiesName parameter, it will be assume that
032: * all cookies name are to be injected into webwork's action, even though
033: * cookiesName is comma-separated by other values, eg (cookie1,*,cookie2). <p/>
034: *
035: * If cookiesName is left empty it will assume that no cookie will be injected
036: * into WebWork's action. <p/>
037: *
038: * If an asterik is present in cookiesValue parameter, it will assume that all
039: * cookies name irrespective of its value will be injected into WebWork's action so
040: * long as the cookie name matches those specified in cookiesName parameter.<p/>
041: *
042: * If cookiesValue is left empty it will assume that all cookie that match the cookieName
043: * parameter will be injected into WebWork's action.<p/>
044: *
045: * The action could implements {@link CookiesAware} in order to have a {@link Map}
046: * of filtered cookies set into it. <p/>
047: *
048: * <!-- END SNIPPET: description -->
049: *
050: *
051: * <!-- START SNIPPET: parameters -->
052: *
053: * <ul>
054: * <li>cookiesName (mandatory) - Name of cookies to be injected into the action. If more
055: * than one cookie name is desired it could be comma-separated.
056: * If all cookies name is desired, it could simply be *, an asterik.
057: * When many cookies name are comma-separated either of the cookie
058: * that match the name in the comma-separated list will be qualified.</li>
059: * <li>cookiesValue (mandatory) - Value of cookies that if its name matches cookieName attribute
060: * and its value matched this, will be injected into WebWork's
061: * action. If more than one cookie name is desired it could be
062: * comma-separated. If left empty, it will assume any value would
063: * be ok. If more than one value is specified (comma-separated)
064: * it will assume a match if either value is matched.
065: * </ul>
066: *
067: * <!-- END SNIPPET: parameters -->
068: *
069: *
070: * <!-- START SNIPPET: extending -->
071: *
072: * <ul>
073: * populateCookieValueIntoStack - this method will decide if this cookie value is qualified to be
074: * populated into the value stack (hence into the action itself)
075: * injectIntoCookiesAwareAction - this method will inject selected cookies (as a java.util.Map) into
076: * action that implements {@link CookiesAware}.
077: * </ul>
078: *
079: * <!-- END SNIPPET: extending -->
080: *
081: * <pre>
082: * <!-- START SNIPPET: example -->
083: *
084: * <!--
085: * This example will inject cookies named either 'cookie1' or 'cookie2' whose
086: * value could be either 'cookie1value' or 'cookie2value' into WebWork's action.
087: * -->
088: * <action ... >
089: * <interceptor-ref name="cookie">
090: * <param name="cookiesName">cookie1, cookie2</param>
091: * <param name="cookiesValue">cookie1value, cookie2value</param>
092: * </interceptor-ref>
093: * ....
094: * </action>
095: *
096: *
097: * <!--
098: * This example will inject cookies named either 'cookie1' or 'cookie2'
099: * regardless of their value into WebWork's action.
100: * -->
101: * <action ... >
102: * <interceptor-ref name="cookie">
103: * <param name="cookiesName">cookie1, cookie2</param>
104: * <param name="cookiesValue">*</param>
105: * <interceptor-ref>
106: * ...
107: * </action>
108: *
109: *
110: * <!--
111: * This example will inject cookies named either 'cookie1' with value
112: * 'cookie1value' or 'cookie2' with value 'cookie2value' into WebWork's
113: * action.
114: * -->
115: * <action ... >
116: * <interceptor-ref name="cookie">
117: * <param name="cookiesName">cookie1</param>
118: * <param name="cookiesValue">cookie1value</param>
119: * </interceptor-ref>
120: * <interceptor-ref name="cookie">
121: * <param name="cookiesName"<cookie2</param>
122: * <param name="cookiesValue">cookie2value</param>
123: * </interceptor-ref>
124: * ....
125: * </action>
126: *
127: * <!--
128: * This example will inject any cookies regardless of its value into
129: * WebWork's action.
130: * -->
131: * <action ... >
132: * <interceptor-ref name="cookie">
133: * <param name="cookiesName">*</param>
134: * <param name="cookiesValue">*</param>
135: * </interceptor-ref>
136: * ...
137: * </action>
138: *
139: * <!-- END SNIPPET: example -->
140: * </pre>
141: *
142: * @see CookiesAware
143: *
144: * @author Matthew Payne
145: * @author tmjee
146: * @version $Date: 2007-01-09 19:08:00 +0100 (Tue, 09 Jan 2007) $ $Id: CookieInterceptor.java 2800 2007-01-09 18:08:00Z tmjee $
147: */
148: public class CookieInterceptor extends AroundInterceptor {
149:
150: private static final long serialVersionUID = 4153142432948747305L;
151:
152: private static final Log LOG = LogFactory
153: .getLog(CookieInterceptor.class);
154:
155: private Set cookiesNameSet = Collections.EMPTY_SET;
156: private Set cookiesValueSet = Collections.EMPTY_SET;
157:
158: /**
159: * Set the <code>cookiesName</code> which if matche will allow the cookie
160: * to be injected into action, could be comma-separated string.
161: *
162: * @param cookiesName
163: */
164: public void setCookiesName(String cookiesName) {
165: if (cookiesName != null)
166: this .cookiesNameSet = TextParseUtil
167: .commaDelimitedStringToSet(cookiesName);
168: }
169:
170: /**
171: * Set the <code>cookiesValue</code> which if matched (together with matching
172: * cookiesName) will caused the cookie to be injected into action, could be
173: * comma-separated string.
174: *
175: * @param cookiesValue
176: */
177: public void setCookiesValue(String cookiesValue) {
178: if (cookiesValue != null)
179: this .cookiesValueSet = TextParseUtil
180: .commaDelimitedStringToSet(cookiesValue);
181: }
182:
183: /**
184: * No operation.
185: */
186: public void destroy() {
187: }
188:
189: /**
190: * No operation.
191: */
192: public void init() {
193: }
194:
195: /**
196: * Inject cookies into action if they match the <code>cookiesName</code>
197: * and <code>cookiesValue</code> configured.
198: *
199: * @param invocation
200: */
201: protected void before(ActionInvocation invocation) throws Exception {
202:
203: if (LOG.isDebugEnabled())
204: LOG.debug("start interception");
205:
206: final OgnlValueStack stack = ActionContext.getContext()
207: .getValueStack();
208: HttpServletRequest request = ServletActionContext.getRequest();
209:
210: // contains selected cookies
211: Map cookiesMap = new LinkedHashMap();
212:
213: Cookie cookies[] = request.getCookies();
214: for (int a = 0; a < cookies.length; a++) {
215: String name = cookies[a].getName();
216: String value = cookies[a].getValue();
217:
218: if (cookiesNameSet.contains("*")) {
219: if (LOG.isDebugEnabled())
220: LOG
221: .debug("contains cookie name [*] in configured cookies name set, cookie with name ["
222: + name
223: + "] with value ["
224: + value
225: + "] will be injected");
226: populateCookieValueIntoStack(name, value, cookiesMap,
227: stack);
228: } else if (cookiesNameSet.contains(cookies[a].getName())) {
229: populateCookieValueIntoStack(name, value, cookiesMap,
230: stack);
231: }
232: }
233:
234: injectIntoCookiesAwareAction(invocation.getAction(), cookiesMap);
235: }
236:
237: /**
238: * No operation.
239: */
240: protected void after(ActionInvocation invocation, String result)
241: throws Exception {
242: if (LOG.isDebugEnabled())
243: LOG.debug("after interception");
244: }
245:
246: /**
247: * Hook that populate cookie value into ognl value stack (hence the action)
248: * if the criteria is satisfied (if the cookie value matches with those configured).
249: *
250: * @param cookieName
251: * @param cookieValue
252: * @param cookiesMap
253: * @param stack
254: */
255: protected void populateCookieValueIntoStack(String cookieName,
256: String cookieValue, Map cookiesMap, OgnlValueStack stack) {
257: if (cookiesValueSet.isEmpty() || cookiesValueSet.contains("*")) {
258: // If the interceptor is configured to accept any cookie value
259: // OR
260: // no cookiesValue is defined, so as long as the cookie name match
261: // we'll inject it into WebWork's action
262: if (LOG.isDebugEnabled()) {
263: if (cookiesValueSet.isEmpty())
264: LOG
265: .debug("no cookie value is configured, cookie with name ["
266: + cookieName
267: + "] with value ["
268: + cookieValue
269: + "] will be injected");
270: else if (cookiesValueSet.contains("*"))
271: LOG
272: .debug("interceptor is configured to accept any value, cookie with name ["
273: + cookieName
274: + "] with value ["
275: + cookieValue
276: + "] will be injected");
277: }
278: cookiesMap.put(cookieName, cookieValue);
279: stack.setValue(cookieName, cookieValue);
280: } else {
281: // if cookiesValues is specified, the cookie's value must match before we
282: // inject them into WebWork's action
283: if (cookiesValueSet.contains(cookieValue)) {
284: if (LOG.isDebugEnabled())
285: LOG
286: .debug("both configured cookie name and value matched, cookie ["
287: + cookieName
288: + "] with value ["
289: + cookieValue
290: + "] will be injected");
291: cookiesMap.put(cookieName, cookieValue);
292: stack.setValue(cookieName, cookieValue);
293: }
294: }
295: }
296:
297: /**
298: * Hook that set the <code>cookiesMap</code> into action that implements
299: * {@link CookiesAware}.
300: *
301: * @param action
302: * @param cookiesMap
303: */
304: protected void injectIntoCookiesAwareAction(Object action,
305: Map cookiesMap) {
306: if (action instanceof CookiesAware) {
307: if (LOG.isDebugEnabled())
308: LOG
309: .debug("action ["
310: + action
311: + "] implements CookiesAware, injecting cookies map ["
312: + cookiesMap + "]");
313: ((CookiesAware) action).setCookiesMap(cookiesMap);
314: }
315: }
316:
317: }
|