001 /* 002 // $Id: //open/mondrian/src/main/mondrian/web/taglib/ResultCache.java#16 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2002-2002 Kana Software, Inc. 007 // Copyright (C) 2002-2008 Julian Hyde and others 008 // All Rights Reserved. 009 // You must accept the terms of that agreement to use this software. 010 // 011 // Andreas Voss, 22 March, 2002 012 */ 013 package mondrian.web.taglib; 014 015 import mondrian.olap.Connection; 016 import mondrian.olap.DriverManager; 017 import mondrian.olap.Query; 018 import mondrian.olap.Result; 019 import mondrian.spi.impl.ServletContextCatalogLocator; 020 021 import org.apache.log4j.Logger; 022 import org.w3c.dom.Document; 023 024 import javax.servlet.ServletContext; 025 import javax.servlet.http.HttpSession; 026 import javax.servlet.http.HttpSessionBindingEvent; 027 import javax.servlet.http.HttpSessionBindingListener; 028 import javax.xml.parsers.ParserConfigurationException; 029 030 /** 031 * holds a query/result pair in the users session 032 */ 033 034 public class ResultCache implements HttpSessionBindingListener { 035 private static final Logger LOGGER = Logger.getLogger(ResultCache.class); 036 private final static String ATTR_NAME = "mondrian.web.taglib.ResultCache."; 037 private Query query = null; 038 private Result result = null; 039 private Document document = null; 040 private ServletContext servletContext; 041 private Connection connection; 042 043 private ResultCache(ServletContext context) { 044 this.servletContext = context; 045 } 046 047 048 /** 049 * Retrieves a cached query. It is identified by its name and the 050 * current session. The servletContext parameter is necessary because 051 * HttpSession.getServletContext was not added until J2EE 1.3. 052 */ 053 public static ResultCache getInstance( 054 HttpSession session, 055 ServletContext servletContext, 056 String name) { 057 String fqname = ATTR_NAME + name; 058 ResultCache resultCache = (ResultCache) session.getAttribute(fqname); 059 if (resultCache == null) { 060 resultCache = new ResultCache(servletContext); 061 session.setAttribute(fqname, resultCache); 062 } 063 return resultCache; 064 } 065 066 public void parse(String mdx) { 067 if (connection != null) { 068 query = connection.parseQuery(mdx); 069 setDirty(); 070 } else { 071 LOGGER.error("null connection"); 072 } 073 } 074 075 public Result getResult() { 076 if (result == null) { 077 long t1 = System.currentTimeMillis(); 078 result = connection.execute(query); 079 long t2 = System.currentTimeMillis(); 080 LOGGER.debug( 081 "Execute query took " + (t2 - t1) + " millisec"); 082 } 083 return result; 084 } 085 086 public Document getDOM() { 087 try { 088 if (document == null) { 089 document = DOMBuilder.build(getResult()); 090 } 091 return document; 092 } catch (ParserConfigurationException e) { 093 LOGGER.error(e); 094 throw new RuntimeException(e.toString()); 095 } 096 } 097 098 /** 099 * Returns the {@link Query}. If you modify the query, call 100 * <code>{@link #setDirty}(true)</code>. 101 */ 102 public Query getQuery() { 103 return query; 104 } 105 106 /** 107 * Sets the query. Automatically calls <code>{@link #setDirty}(true)</code>. 108 */ 109 public void setQuery(Query query) { 110 this.query = query; 111 setDirty(); 112 } 113 /** 114 * set to dirty after you have modified the query to force a recalcuation 115 */ 116 public void setDirty() { 117 result = null; 118 document = null; 119 } 120 121 /** 122 * create a new connection to Mondrian 123 */ 124 public void valueBound(HttpSessionBindingEvent ev) { 125 String connectString = 126 servletContext.getInitParameter("connectString"); 127 LOGGER.debug("connectString: " + connectString); 128 this.connection = 129 DriverManager.getConnection( 130 connectString, 131 new ServletContextCatalogLocator(servletContext)); 132 if (this.connection == null) { 133 throw new RuntimeException( 134 "No ROLAP connection from connectString: " 135 + connectString); 136 } 137 } 138 139 /** 140 * close connection 141 */ 142 public void valueUnbound(HttpSessionBindingEvent ev) { 143 if (connection != null) { 144 connection.close(); 145 } 146 } 147 148 149 } 150 151 // End ResultCache.java