/*
* 修改记录
* 2014-2-7 STORY #7563 -nosession的cookiestore支持domain
*/
package com.hundsun.jresplus.web.nosession.cookie;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hundsun.jresplus.common.util.ArrayUtil;
import com.hundsun.jresplus.common.util.StringUtil;
import com.hundsun.jresplus.web.nosession.SessionEncoderException;
/**
*
* @author LeoHu copy by sagahl
*
*/
class CookiesManagerImpl implements CookiesManager {
private final static Logger log = LoggerFactory
.getLogger(CookiesManagerImpl.class);
private static final String COOKIE_NAME_PATTERN_SUFFIX = "(\\d+)";
private int maxLength, maxCount;
public void setMaxLength(int maxLength) {
this.maxLength = maxLength;
}
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
private static class CookieInfo implements Comparable<CookieInfo> {
public final int index;
public final String value;
public CookieInfo(int index, String value) {
this.index = index;
this.value = value;
}
public int compareTo(CookieInfo o) {
return index - o.index;
}
}
private String mergeCookies(String cookieName, List<CookieInfo> cookieList) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cookieList.size(); i++) {
CookieInfo info = null;
for (CookieInfo cookieInfo : cookieList) {
if (cookieInfo.index == i) {
info = cookieInfo;
break;
}
}
if (info == null) {
log.warn("the cookie index error,the cookieName = "
+ cookieName + ".the lost array No is:" + i);
return null;
} else {
sb.append(info.value);
}
}
return sb.toString();
}
public String readCookieValue(HttpServletRequest servletRequest,
String cookieName) {
javax.servlet.http.Cookie[] cookies = servletRequest.getCookies();
List<CookieInfo> cookieList = new ArrayList<CookieInfo>();
Pattern namePattern = Pattern.compile(cookieName
+ COOKIE_NAME_PATTERN_SUFFIX);
if (cookies == null) {
return null;
}
for (javax.servlet.http.Cookie cookie : cookies) {
if (cookieName.equals(cookie.getName())) {
return cookie.getValue();
}
Matcher matcher = namePattern.matcher(cookie.getName());
if (matcher.matches()) {
int index = Integer.parseInt(matcher.group(1));
CookieInfo cookieInfo = new CookieInfo(index,
StringUtil.trimToNull(cookie.getValue()));
cookieList.add(cookieInfo);
}
}
Collections.sort(cookieList);
return mergeCookies(cookieName, cookieList);
}
private void clearGarbage(HttpServletRequest servletRequest,
HttpServletResponse servletResponse, String cookieName,
int startNum, String path, String domain) {
Pattern namePattern = Pattern.compile(cookieName
+ COOKIE_NAME_PATTERN_SUFFIX);
javax.servlet.http.Cookie[] cookies = servletRequest.getCookies();
if (ArrayUtil.isEmpty(cookies)) {
return;
}
for (javax.servlet.http.Cookie cookie : cookies) {
if (cookieName.equals(cookie.getName()) && startNum != 0) {
cookie.setMaxAge(0);
cookie.setValue(null);
cookie.setPath(path);
if (StringUtil.isEmpty(domain) == false) {
cookie.setDomain(domain);
}
servletResponse.addCookie(cookie);
}
Matcher matcher = namePattern.matcher(cookie.getName());
if (matcher.matches()) {
int index = Integer.parseInt(matcher.group(1));
if (index > startNum) {
cookie.setMaxAge(0);
cookie.setValue(null);
cookie.setPath(path);
if (StringUtil.isEmpty(domain) == false) {
cookie.setDomain(domain);
}
servletResponse.addCookie(cookie);
}
}
}
}
public void writeCookie(HttpServletRequest servletRequest,
HttpServletResponse servletResponse,
com.hundsun.jresplus.web.nosession.cookie.Cookie cookie)
throws SessionEncoderException {
int startNum = 0;
if (cookie.getValue() != null) {
if (cookie.getValue().length() > maxLength * maxCount) {
log.error("Cookie store full! All session attributes will be LOST! the cookies length="
+ cookie.getValue().length()
+ ", and the maxlength="
+ maxLength);
throw new SessionEncoderException(
"Cookie store full! All session attributes will be LOST!");
}
if (cookie.getValue().length() + cookie.getName().length() > maxLength) {
for (int beginOffset = 0, i = 1; beginOffset < cookie
.getValue().length(); beginOffset += (maxLength - cookie
.getName().length()), i++) {
int endOffset = Math.min(beginOffset
+ (maxLength - cookie.getName().length()), cookie
.getValue().length());
com.hundsun.jresplus.web.nosession.cookie.Cookie harpCookie = new com.hundsun.jresplus.web.nosession.cookie.Cookie(
cookie.getName() + startNum, cookie.getValue()
.substring(beginOffset, endOffset),
cookie.isHttpOnly(), cookie.getMaxAge(),
cookie.getPath(), cookie.getDomain());
servletResponse.addCookie(harpCookie);
startNum = i;
}
} else {
servletResponse.addCookie(cookie);
}
} else {
startNum = -1;
}
clearGarbage(servletRequest, servletResponse, cookie.getName(),
startNum, cookie.getPath(), cookie.getDomain());
}
}