package greencode.http;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpSession;
import org.apache.catalina.session.StandardSession;
import org.apache.catalina.session.StandardSessionFacade;
import greencode.jscript.dom.$Window;
import greencode.jscript.dom.Window;
import greencode.jscript.dom.WindowHandle;
import greencode.kernel.GreenCodeConfig;
import greencode.util.GenericReflection;
public final class ViewSession implements Serializable {
private static final long serialVersionUID = 1L;
private final ScheduledExecutorService scheduled = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> currentSheduled;
private final ViewSessionContext context;
private final int id;
private final long creationTime = System.currentTimeMillis();
private long lastAccessedTime = creationTime, thisAccessedTime = creationTime;
private int maxInactiveInterval = GreenCodeConfig.Server.View.Session.maxInactiveInterval;
boolean isNew = true;
private final StandardSession session;
private final ViewSession This = this;
private final Runnable task = new Runnable() {
public void run() {
if (!This.session.isValid() || This.thisAccessedTime + (maxInactiveInterval * 1000) < System.currentTimeMillis()) {
// Console.log(LogMessage.getMessage("green-0026",
// This.getId()));
This.invalidate();
}
}
};
private final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
private final static Field f = GenericReflection.NoThrow.getDeclaredField(StandardSessionFacade.class, "session");
ViewSession(int id, HttpSession session, ViewSessionContext context) {
this.session = (StandardSession) GenericReflection.NoThrow.getValue(f, session);
this.id = id;
this.context = context;
context.addView(id, this);
setMaxInactiveInterval(maxInactiveInterval);
// System.out.println("View session("+id+") created");
}
public void access() {
this.lastAccessedTime = this.thisAccessedTime;
this.thisAccessedTime = System.currentTimeMillis();
session.access();
}
public Object getAttribute(String arg0) {
return attributes.get(arg0);
}
public Enumeration<String> getAttributeNames() {
return attributes.keys();
}
public long getCreationTime() {
return creationTime;
}
public int getId() {
return id;
}
public long getLastAccessedTime() {
return lastAccessedTime;
}
public int getMaxInactiveInterval() {
return maxInactiveInterval;
}
public ViewSessionContext getViewSessionContext() {
return context;
}
public Object getValue(String arg0) {
return attributes.values();
}
public String[] getValueNames() {
return (String[]) attributes.keySet().toArray();
}
public void invalidate() {
Map<Integer, Map<String, Object>> conversationMap = Conversation.getConverstionMap(this);
for (Integer key : conversationMap.keySet()) {
final Conversation conversation = new Conversation(this, key);
Map<Class<? extends Window>, Window> list = $Window.getMap(conversation);
for (Class<? extends Window> clazz : list.keySet()) {
WindowHandle.removeInstance(clazz, conversation);
}
}
attributes.clear();
context.removeViewSession(id);
currentSheduled.cancel(true);
scheduled.shutdownNow();
}
public boolean isValid() {
return context.views.containsKey(id);
}
public boolean isNew() {
return isNew;
}
public void putValue(String arg0, Object arg1) {
attributes.put(arg0, arg1);
}
public void removeAttribute(String arg0) {
attributes.remove(arg0);
}
public void removeValue(String arg0) {
attributes.values().remove(arg0);
}
public void setAttribute(String arg0, Object arg1) {
attributes.put(arg0, arg1);
}
public void setMaxInactiveInterval(int arg0) {
maxInactiveInterval = arg0;
if (currentSheduled != null)
currentSheduled.cancel(true);
currentSheduled = scheduled.scheduleWithFixedDelay(task, maxInactiveInterval, maxInactiveInterval, TimeUnit.SECONDS);
}
}