/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nutch.webapp.common;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Locale;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Preferences represents (extendable) configuration object that is persistable
* into user browser (as cookie).
*
* Cookie is in format key-1<KEYVALSEPARATOR>value-1<VALVALSEPARATOR>key-2<KEYVALSEPARATOR>value-2<VALVALSEPARATOR>key-n<KEYVALSEPARATOR>value-n
*/
public class Preferences extends HashMap {
private static final long serialVersionUID = 1;
public static final String KEY_LOCALE = "L";
public static final String KEY_RESULTS_PER_PAGE = "R";
public static final String KEY_HITS_PER_DUP = "S";
public static final String KEY_DUP_FIELD = "D";
static final String DEFAULTKEYVALSEPARATOR = "_";
static final String DEFAULTVALVALSEPARATOR = "-";
/**
* Name of web ui cookie that stores users cutomized user preferences.
*/
public static final String COOKIE_NAME = "NUTCH";
/**
* Default preferences, used for all who have not customized.
*/
static final Preferences DEFAULTS = new Preferences();
static {
// results per page
DEFAULTS.put(KEY_RESULTS_PER_PAGE, "10");
// dup field
DEFAULTS.put(KEY_DUP_FIELD, "site");
}
/**
* @return locale of user (from preferences if set, or from request)
*/
public Locale getLocale(HttpServletRequest request) {
if (containsKey(KEY_LOCALE)) {
return new Locale((String) get(KEY_LOCALE));
} else {
return request.getLocale();
}
}
/**
* Persist Preferences as cookie.
* @param request
* @param response
* @param prefs preferences object to persist
*/
public static void setPreferencesCookie(HttpServletRequest request,
HttpServletResponse response, Preferences prefs) {
if (DEFAULTS.equals(prefs)) {
removeCookie(response);
} else {
setPreferencesCookie(response, prefs);
}
}
private static void setPreferencesCookie(HttpServletResponse response,
Preferences prefs) {
Cookie prefscookie = new Cookie(COOKIE_NAME, prefs.toString());
prefscookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(prefscookie);
}
/**
* Remove cookie from browser
*
* @param response
*/
public static void removeCookie(HttpServletResponse response) {
Cookie prefscookie = new Cookie(COOKIE_NAME, "");
prefscookie.setMaxAge(-1);
response.addCookie(prefscookie);
}
/**
* Parse Preferences from cookie.
*
* @param request
*/
public static Preferences parseCookie(HttpServletRequest request) {
// find right cookie
Cookie[] c = request.getCookies();
if (c != null) {
for (int i = 0; i < c.length; i++) {
if (COOKIE_NAME.equals(c[i].getName())) {
return Preferences.parse(c[i].getValue());
}
}
}
return DEFAULTS;
}
/**
* Parse a String into Preferences object using default separators
* @param data
* @return
*/
public static Preferences parse(String data) {
return parse(data,DEFAULTVALVALSEPARATOR, DEFAULTKEYVALSEPARATOR);
}
/**
* Parse a String into a Preferences object
* @param data String to parse
* @param valueValueSeparator delimiter between keyValue pairs
* @param keyValueSeparator delimiter between key & value
* @return parsed Preferences
*/
public static Preferences parse(String data, String valueValueSeparator, String keyValueSeparator) {
Preferences p = new Preferences();
p.putAll(DEFAULTS);
String[] dataitems = data.split(valueValueSeparator);
for (int i = 0; i < dataitems.length; i++) {
String keyvalue[] = dataitems[i].split(keyValueSeparator);
if (keyvalue.length == 2) {
try {
p.put(keyvalue[0], URLDecoder.decode((String) keyvalue[1], "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
return p;
}
/**
* Return int value or default if non existing.
* @param name
* @param defaultVal
* @return
*/
public int getInt(String name, int defaultVal) {
try {
return get(name) == null ? defaultVal : Integer
.parseInt((String) get(name));
} catch (Exception e) {
return defaultVal;
}
}
/**
* Return String value or default if non existing.
* @param name
* @param defaultVal
* @return
*/
public String getString(String name, String defaultVal) {
return get(name) == null ? defaultVal : (String) get(name);
}
public String toString() {
StringBuffer txt = new StringBuffer();
Object[] keys = keySet().toArray();
for (int i = 0; i < keys.length; i++) {
try {
txt.append(keys[i].toString()).append(DEFAULTKEYVALSEPARATOR).append(
URLEncoder.encode((String) get(keys[i]), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (i < keys.length - 1) {
txt.append(DEFAULTVALVALSEPARATOR);
}
}
return txt.toString();
}
/**
* Get (cached) Preferences instance from request (first from request
* attribute then from cookie).
*
* @param request
* @return Preferences object from request or null if not available
*/
public static Preferences getPreferences(final HttpServletRequest request) {
Preferences prefs = (Preferences) request.getAttribute(Preferences.class
.getName());
// processing locale
if (prefs == null) {
prefs = parseCookie(request);
request.setAttribute(Preferences.class.getName(), prefs);
}
return prefs;
}
}