package com.inepex.ineFrame.server.monitor;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import com.google.gwt.user.client.rpc.IsSerializable;
import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
@SuppressWarnings("serial")
public class SessionMonitorServlet extends HttpServlet implements HttpSessionListener {
	
	private static List<HttpSession> sessions = new ArrayList<HttpSession>();
	private static Long numberOfSessions = 0L;
	
	@Inject
	public SessionMonitorServlet() {
		// TODO Auto-generated constructor stub
	}
	
	@Override
	public void init() throws ServletException {
		System.out.println("started");
		super.init();
	}

	@Override	
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.getWriter().println("Number of active sessions: " + numberOfSessions);
		List<HttpSession> copy;
		synchronized (sessions) {
			copy = new ArrayList<HttpSession>(sessions);
		}
		for (HttpSession sess : copy){
			
			Long approximateSizeInByte = 0L;
			Enumeration<String> attributeNames = sess.getAttributeNames();
			while (attributeNames.hasMoreElements()){
				String name = attributeNames.nextElement();
				if (sess.getAttribute(name) instanceof IsSerializable || sess.getAttribute(name) instanceof Serializable){
					ByteArrayOutputStream bos = new ByteArrayOutputStream();
					ObjectOutput out = new ObjectOutputStream(bos);
					
					out.writeObject(sess.getAttribute(name));
					byte[] bytes = bos.toByteArray();
					approximateSizeInByte += bytes.length;
				}

			}		
			resp.getWriter().println("Size of " + sess.getId() + ": " + approximateSizeInByte);
			
		}
		
		
	}


	@Override
	public void sessionCreated(HttpSessionEvent arg0) {
		synchronized (numberOfSessions) {
			numberOfSessions++;
		}
		synchronized (sessions) {
			sessions.add(arg0.getSession());			
		}

	}


	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {
		synchronized (numberOfSessions) {
			numberOfSessions--;
		}
		synchronized (sessions) {
			sessions.remove(arg0.getSession());			
		}
	}
}

@@ -287,16 +287,64 @@
 l.List;%0D
+%0Aimport java.util.concurrent.atomic.AtomicLong;%0D
 %0A%0D%0Aimpor
@@ -1001,16 +1001,22 @@
  static 
+Atomic
 Long num
@@ -1031,18 +1031,34 @@
 sions = 
+new AtomicLong(
 0L
+)
 ;%0D%0A%09%0D%0A%09@
@@ -1104,51 +1104,8 @@
  %7B%0D%0A
-%09%09// TODO Auto-generated constructor stub%0D%0A
 %09%7D%0D%0A
@@ -1423,24 +1423,30 @@
 erOfSessions
+.get()
 );%0D%0A%09%09List%3CH
@@ -2349,38 +2349,24 @@
  arg0) %7B%0D%0A%09%09
-synchronized (
 numberOfSess
@@ -2373,40 +2373,31 @@
 ions
-) %7B%0D%0A%09%09%09numberOfSessions++
+.incrementAndGet()
 ;%0D%0A%09%09
-%7D
 %0D%0A%09%09
@@ -2548,30 +2548,16 @@
 0) %7B%0D%0A%09%09
-synchronized (
 numberOf
@@ -2568,40 +2568,31 @@
 ions
-) %7B%0D%0A%09%09%09numberOfSessions--
+.decrementAndGet()
 ;%0D%0A%09%09
-%7D
 %0D%0A%09%09

monitor objects