001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.wicket.markup.html.form.persistence;
018:
019: import javax.servlet.http.Cookie;
020:
021: import org.apache.wicket.RequestCycle;
022: import org.apache.wicket.markup.html.form.FormComponent;
023: import org.apache.wicket.protocol.http.WebRequest;
024: import org.apache.wicket.protocol.http.WebResponse;
025: import org.apache.wicket.util.time.Time;
026: import org.slf4j.Logger;
027: import org.slf4j.LoggerFactory;
028:
029: /**
030: * This class implements IValuePersister by means of HTTP cookies.
031: *
032: * @author Juergen Donnerstag
033: * @author Jonathan Locke
034: */
035: public class CookieValuePersister implements IValuePersister {
036: private static final long serialVersionUID = 1L;
037:
038: /** Logging */
039: private final static Logger log = LoggerFactory
040: .getLogger(CookieValuePersister.class);
041:
042: /**
043: * @see org.apache.wicket.markup.html.form.persistence.IValuePersister#clear(org.apache.wicket.markup.html.form.FormComponent)
044: */
045: public void clear(final FormComponent component) {
046: final Cookie cookie = getCookie(component);
047: if (cookie != null) {
048: clear(cookie);
049: if (log.isDebugEnabled()) {
050: log.debug("Cookie for " + component + " removed");
051: }
052: }
053: }
054:
055: /**
056: * @see org.apache.wicket.markup.html.form.persistence.IValuePersister#load(org.apache.wicket.markup.html.form.FormComponent)
057: */
058: public void load(final FormComponent component) {
059: final Cookie cookie = getCookie(component);
060: if (cookie != null) {
061: final String value = cookie.getValue();
062: if (value != null) {
063: // Assign the retrieved/persisted value to the component
064: component.setModelValue(value
065: .split(FormComponent.VALUE_SEPARATOR));
066: }
067: }
068: }
069:
070: /**
071: * @see org.apache.wicket.markup.html.form.persistence.IValuePersister#save(org.apache.wicket.markup.html.form.FormComponent)
072: */
073: public void save(final FormComponent component) {
074: final String name = getName(component);
075: final String value = component.getValue();
076:
077: Cookie cookie = getCookie(component);
078: if (cookie == null) {
079: cookie = new Cookie(name, value == null ? "" : value);
080: } else {
081: cookie.setValue(value == null ? "" : value);
082: }
083: cookie.setSecure(false);
084: cookie.setMaxAge(getSettings().getMaxAge());
085:
086: save(cookie);
087: }
088:
089: /**
090: * @param component Component to get name for
091: * @return The name of the component.
092: */
093: protected String getName(final FormComponent component) {
094: return component.getPageRelativePath();
095: }
096:
097: /**
098: * Convenience method for deleting a cookie by name. Delete the cookie by
099: * setting its maximum age to zero.
100: *
101: * @param cookie
102: * The cookie to delete
103: */
104: private void clear(final Cookie cookie) {
105: if (cookie != null) {
106: // Delete the cookie by setting its maximum age to zero
107: cookie.setMaxAge(0);
108: cookie.setValue(null);
109:
110: save(cookie);
111: }
112: }
113:
114: /**
115: * Gets debug info as a string for the given cookie.
116: *
117: * @param cookie
118: * the cookie to debug.
119: * @return a string that represents the internals of the cookie.
120: */
121: private String cookieToDebugString(final Cookie cookie) {
122: return "[Cookie " + " name = " + cookie.getName()
123: + ", value = " + cookie.getValue() + ", domain = "
124: + cookie.getDomain() + ", path = " + cookie.getPath()
125: + ", maxAge = "
126: + Time.valueOf(cookie.getMaxAge()).toDateString() + "("
127: + cookie.getMaxAge() + ")" + "]";
128: }
129:
130: /**
131: * Gets the cookie for a given persistent form component. The name of the
132: * cookie will be the component's page relative path (@see
133: * org.apache.wicket.markup.html.form.FormComponent#getPageRelativePath()). Be reminded
134: * that only if the cookie data have been provided by the client (browser),
135: * they'll be accessible by the server.
136: *
137: * @param component
138: * The form component
139: * @return The cookie for the component or null if none is available
140: */
141: private Cookie getCookie(final FormComponent component) {
142: // Gets the cookie's name
143: final String name = getName(component);
144:
145: // Get all cookies attached to the Request by the client browser
146: Cookie[] cookies = getCookies();
147: if (cookies != null) {
148: for (int i = 0; i < cookies.length; i++) {
149: Cookie cookie = cookies[i];
150:
151: // Names must match and Value must not be empty
152: if (cookie.getName().equals(name)) {
153: // cookies with no value do me no good!
154: if (cookie.getValue() != null
155: && cookie.getValue().length() > 0) {
156: if (log.isDebugEnabled()) {
157: log.debug("Got cookie: "
158: + cookieToDebugString(cookie));
159: }
160: return cookie;
161: } else {
162: if (log.isDebugEnabled()) {
163: log
164: .debug("Got cookie "
165: + name
166: + ", but it had no value; returning null");
167: }
168: }
169: }
170: }
171: }
172:
173: return null;
174: }
175:
176: /**
177: * Gets any cookies for request.
178: *
179: * @return Any cookies for this request
180: */
181: private Cookie[] getCookies() {
182: try {
183: return getWebRequest().getCookies();
184: } catch (NullPointerException ex) {
185: // Ignore any app server problem here
186: }
187:
188: return new Cookie[0];
189: }
190:
191: /**
192: * Persister defaults are maintained centrally by the Application.
193: *
194: * @return Persister default value
195: */
196: private CookieValuePersisterSettings getSettings() {
197: return RequestCycle.get().getApplication()
198: .getSecuritySettings()
199: .getCookieValuePersisterSettings();
200: }
201:
202: /**
203: * Convenience method to get the http request.
204: *
205: * @return WebRequest related to the RequestCycle
206: */
207: private WebRequest getWebRequest() {
208: return (WebRequest) RequestCycle.get().getRequest();
209: }
210:
211: /**
212: * Convinience method to get the http response.
213: *
214: * @return WebResponse related to the RequestCycle
215: */
216: private WebResponse getWebResponse() {
217: return (WebResponse) RequestCycle.get().getResponse();
218: }
219:
220: /**
221: * Persist/save the data using Cookies.
222: *
223: * @param cookie
224: * The Cookie to be persisted.
225: * @return The cookie provided
226: */
227: private Cookie save(final Cookie cookie) {
228: if (cookie == null) {
229: return null;
230: } else {
231: final String comment = getSettings().getComment();
232: if (comment != null) {
233: cookie.setComment(comment);
234: }
235:
236: final String domain = getSettings().getDomain();
237: if (domain != null) {
238: cookie.setDomain(domain);
239: }
240:
241: cookie.setPath("/");
242: //cookie.setPath(getWebRequest().getContextPath());
243:
244: cookie.setVersion(getSettings().getVersion());
245: cookie.setSecure(getSettings().getSecure());
246:
247: getWebResponse().addCookie(cookie);
248:
249: if (log.isDebugEnabled()) {
250: log.debug("saved: " + cookieToDebugString(cookie));
251: }
252:
253: return cookie;
254: }
255: }
256: }
|