package hep.aida.web.taglib.util; import hep.aida.IAnalysisFactory; import hep.aida.IManagedObject; import hep.aida.ITree; import hep.aida.ITreeFactory; import hep.aida.web.taglib.PlotterRegistry; import hep.aida.web.taglib.TreeTagSupport; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import javax.servlet.jsp.JspException; /** * * @author The FreeHEP team @ SLAC */ public class TreeUtils implements ServletContextListener, HttpSessionListener { private static Hashtable treeMap = new Hashtable();; private static ITreeFactory treeFactory = IAnalysisFactory.create().createTreeFactory(); public void contextInitialized(ServletContextEvent servletContextEvent) { //treeMap = new Hashtable(); } public void contextDestroyed(ServletContextEvent servletContextEvent) { treeMap.clear(); } public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { System.out.println("**** Destroying session "+httpSessionEvent.getSession().getId()); String sessionId = httpSessionEvent.getSession().getId(); String context = httpSessionEvent.getSession().getServletContext().getServletContextName(); synchronized (treeMap) { Enumeration keys = treeMap.keys(); while ( keys.hasMoreElements() ) { String storeName = (String) keys.nextElement(); TreeSession treeSession = (TreeSession) treeMap.get(storeName); if ( treeSession.containsSessionId(sessionId) ) { try { closeTree(storeName, sessionId); } catch (IOException ioe) { LogUtils.log().warn("Problems closing tree "+storeName+" for session "+sessionId+" in context "+context); } } } } //Also clear the plotter registry Object obj = httpSessionEvent.getSession().getAttribute(PlotterRegistry.REGISTRY_SESSION_NAME); if ( obj != null ) { System.out.println("************* Clearing plotter registry "); ((PlotterRegistry)obj).clear(); } } public void sessionCreated(HttpSessionEvent httpSessionEvent) { } public static ITree getTree(TreeTagSupport tag, String sessionId) throws IOException { return getTree(tag.getStoreName(), tag.getStoreType(), tag.getOptions(), sessionId); } public static ITree getTree(String storeName, String storeType, String options, String sessionId) throws IOException { ITree tree; synchronized (treeMap) { tree = getTree(storeName, sessionId); if (tree == null) { long t0 = System.currentTimeMillis(); tree = treeFactory.create(storeName, storeType, true,false, options); treeMap.put(storeName, new TreeSession(tree, sessionId)); long t1 = System.currentTimeMillis(); LogUtils.log().warn(" Adding tree "+storeName+" to map for session "+sessionId+". *** Create ITree Time: "+(t1-t0)+" ms. Open trees: "+treeMap.size()); } } return tree; } public static ITree getTree(String storeName, String sessionId) { ITree tree; synchronized (treeMap) { TreeSession treeSession = (TreeSession) treeMap.get(storeName); if ( treeSession == null ) return null; treeSession.addSessionId(sessionId); tree = treeSession.tree(); LogUtils.log().debug("Getting tree "+storeName+" from map for session "+sessionId+". Open trees: "+treeMap.size()); } return tree; } public static void closeTree(String storeName, String sessionId) throws IOException { Object obj = treeMap.get(storeName); if ( obj != null ) { TreeSession treeSession = (TreeSession) obj; treeSession.removeSessionId(sessionId); if ( ! treeSession.hasSessionId() ) { ITree tree = treeSession.tree(); tree.close(); treeMap.remove(storeName); // LogUtils.log().debug("Removing managed objects "); // // String[] objs = tree.listObjectNames(); // for ( int i = 0; i < objs.length; i++ ) { // tree.rm(objs[i]); // } LogUtils.log().debug("Closed tree "+storeName+" for sessionId "+sessionId+". Open trees: "+treeMap.size()); } else LogUtils.log().debug("Detached tree "+storeName+" from sessionId "+sessionId+". Open trees: "+treeMap.size()); } else LogUtils.log().warn("Attempt to close non existent tree "+storeName+" Open trees: "+treeMap.size()); } private static class TreeSession { private ITree tree; private ArrayList sessionIds = new ArrayList(); TreeSession(ITree tree, String sessionId) { this.tree = tree; sessionIds.add(sessionId); } ITree tree() { return tree; } void addSessionId(String sessionId) { if ( sessionIds.contains(sessionId) ) return; sessionIds.add(sessionId); } void removeSessionId(String sessionId) { sessionIds.remove(sessionId); } boolean containsSessionId(String sessionId) { return sessionIds.contains(sessionId); } boolean hasSessionId() { return sessionIds.size() != 0; } } }