package jp.troter.servlet.httpsession.spi.impl;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import jp.troter.servlet.httpsession.spi.SessionStateManager;
import jp.troter.servlet.httpsession.spi.SessionValueSerializer;
import jp.troter.servlet.httpsession.spi.SpyMemcachedInitializer;
import jp.troter.servlet.httpsession.state.DefaultSessionState;
import jp.troter.servlet.httpsession.state.SessionState;

public class SpyMemcachedSessionStateManager extends SessionStateManager {

    public static final String KEY_PREFIX = "httpsession";

    protected SpyMemcachedInitializer initializer;

    protected SessionValueSerializer serializer;

    @SuppressWarnings("unchecked")
    @Override
    public SessionState loadState(String sessionId) {
        Object obj = getSpyMemcachedInitializer().getMemcachedClient().get(key(sessionId));
        Map<String, Object> attributes = new HashMap<String, Object>();
        if (obj != null) {
            Map<String, Object> rawAttributes = (Map<String, Object>) obj;
            for (String key : rawAttributes.keySet()) {
                try {
                    attributes.put(key, rawAttributes.get(key));
                } catch (Exception UserHttpSessionSerializationException) {
                }
            }
        }

        return new DefaultSessionState(attributes);
    }

    @Override
    public void updateState(String sessionId, SessionState sessionState) {
        Map<String, Object> attributes = new HashMap<String, Object>();

        for (Enumeration<?> e = sessionState.getAttributeNames(); e.hasMoreElements();) {
            String name = (String)e.nextElement();
            Object value = sessionState.getAttribute(name);
            if (value == null) { continue; }
            try {
                attributes.put(name, value);
            } catch (Exception UserHttpSessionSerializationException) {
            }
        }

        getSpyMemcachedInitializer().getMemcachedClient().set(key(sessionId), getTimeoutSecond(), attributes);
    }

    @Override
    public void removeState(String sessionId) {
        getSpyMemcachedInitializer().getMemcachedClient().delete(key(sessionId));
    }

    @Override
    public int getTimeoutSecond() {
        return getSpyMemcachedInitializer().getSessionTimeout();
    }

    protected String key(String sessionId) {
        return KEY_PREFIX + "/" + sessionId;
    }

    protected SpyMemcachedInitializer getSpyMemcachedInitializer() {
        if (initializer == null) {
            initializer = SpyMemcachedInitializer.newInstance();
        }
        return initializer;
    }

    protected SessionValueSerializer getSessionValueSerializer() {
        if (serializer == null) {
            serializer = SessionValueSerializer.newInstance();
        }
        return serializer;
    }
}

@@ -436,16 +436,74 @@
 State;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 public c
@@ -570,16 +570,113 @@
 ager %7B%0A%0A
+    private static Logger log = LoggerFactory.getLogger(SpyMemcachedSessionStateManager.class);%0A%0A
     publ
@@ -924,32 +924,122 @@
 ng sessionId) %7B%0A
+        Map%3CString, Object%3E attributes = new HashMap%3CString, Object%3E();%0A        try %7B%0A    
         Object o
@@ -1126,98 +1126,76 @@
     
-Map%3CString, Object%3E attributes = new HashMap%3CString, Object%3E();%0A        if (obj != null) %7B
+    if (obj == null) %7B return new DefaultSessionState(attributes); %7D
 %0A   
@@ -1270,94 +1270,8 @@
 bj;%0A
-            for (String key : rawAttributes.keySet()) %7B%0A                try %7B%0A        
     
@@ -1296,14 +1296,12 @@
 .put
-(key, 
+All(
 rawA
@@ -1313,83 +1313,35 @@
 utes
-.get(key));%0A                %7D catch (Exception UserHttpSessionSerialization
+);%0A        %7D catch (Runtime
 Exce
@@ -1337,32 +1337,34 @@
 RuntimeException
+ e
 ) %7B%0A            
@@ -1367,27 +1367,127 @@
     
-    %7D%0A            %7D
+log.warn(%22Memcached exception occurred at get method. session_id=%22 + sessionId, e);%0A            removeState(sessionId);
 %0A   
@@ -1714,17 +1714,16 @@
 ect%3E();%0A
-%0A
         
@@ -1964,30 +1964,8 @@
 ; %7D%0A
-            try %7B%0A    
     
@@ -2012,98 +2012,29 @@
     
+ %7D%0A
      
-%7D catch (Exception UserHttpSessionSerializationException) %7B%0A            %7D%0A        %7D%0A%0A
+   try %7B%0A    
     
@@ -2132,32 +2132,177 @@
 ), attributes);%0A
+        %7D catch (RuntimeException e) %7B%0A            log.warn(%22Memcached exception occurred at set method. session_id=%22 + sessionId, e);%0A        %7D%0A
     %7D%0A%0A    @Over
@@ -2346,32 +2346,50 @@
 ng sessionId) %7B%0A
+        try %7B%0A    
         getSpyMe
@@ -2450,24 +2450,172 @@
 essionId));%0A
+        %7D catch (RuntimeException e) %7B%0A            log.warn(%22Memcached exception occurred at delete method. session_id=%22 + sessionId, e);%0A        %7D%0A
     %7D%0A%0A    @

add log