/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.web;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import org.h2.bnf.Bnf;
import org.h2.message.TraceSystem;
import org.h2.util.New;
/**
* The web session keeps all data of a user session.
* This class is used by the H2 Console.
*/
class WebSession {
private static final int MAX_HISTORY = 1000;
/**
* The last time this client sent a request.
*/
long lastAccess;
/**
* The session attribute map.
*/
HashMap<String, Object> map = New.hashMap();
/**
* The current locale.
*/
Locale locale;
/**
* The currently executing statement.
*/
Statement executingStatement;
/**
* The current updatable result set.
*/
ResultSet result;
private WebServer server;
private ArrayList<String> commandHistory = New.arrayList();
private Connection conn;
private DatabaseMetaData meta;
private DbContents contents = new DbContents();
private DbContextRule columnRule;
private DbContextRule newAliasRule;
private DbContextRule schemaRule;
private DbContextRule tableRule;
private DbContextRule aliasRule;
private DbContextRule columnAliasRule;
private Bnf bnf;
private boolean shutdownServerOnDisconnect;
WebSession(WebServer server) {
this.server = server;
}
/**
* Put an attribute value in the map.
*
* @param key the key
* @param value the new value
*/
void put(String key, Object value) {
map.put(key, value);
}
/**
* Get the value for the given key.
*
* @param key the key
* @return the value
*/
Object get(String key) {
if ("sessions".equals(key)) {
return server.getSessions();
}
return map.get(key);
}
/**
* Remove a session attribute from the map.
*
* @param key the key
*/
void remove(String key) {
map.remove(key);
}
/**
* Get the BNF object.
*
* @return the BNF object
*/
Bnf getBnf() {
return bnf;
}
/**
* Load the SQL grammar BNF.
*/
void loadBnf() {
try {
Bnf newBnf = Bnf.getInstance(null);
columnRule = new DbContextRule(contents, DbContextRule.COLUMN);
newAliasRule = new DbContextRule(contents, DbContextRule.NEW_TABLE_ALIAS);
aliasRule = new DbContextRule(contents, DbContextRule.TABLE_ALIAS);
tableRule = new DbContextRule(contents, DbContextRule.TABLE);
schemaRule = new DbContextRule(contents, DbContextRule.SCHEMA);
columnAliasRule = new DbContextRule(contents, DbContextRule.COLUMN_ALIAS);
newBnf.updateTopic("column_name", columnRule);
newBnf.updateTopic("new_table_alias", newAliasRule);
newBnf.updateTopic("table_alias", aliasRule);
newBnf.updateTopic("column_alias", columnAliasRule);
newBnf.updateTopic("table_name", tableRule);
newBnf.updateTopic("schema_name", schemaRule);
newBnf.linkStatements();
bnf = newBnf;
} catch (Exception e) {
// ok we don't have the bnf
server.traceError(e);
}
}
/**
* Get the SQL statement from history.
*
* @param id the history id
* @return the SQL statement
*/
String getCommand(int id) {
return commandHistory.get(id);
}
/**
* Add a SQL statement to the history.
*
* @param sql the SQL statement
*/
void addCommand(String sql) {
if (sql == null) {
return;
}
sql = sql.trim();
if (sql.length() == 0) {
return;
}
if (commandHistory.size() > MAX_HISTORY) {
commandHistory.remove(0);
}
int idx = commandHistory.indexOf(sql);
if (idx >= 0) {
commandHistory.remove(idx);
}
commandHistory.add(sql);
}
/**
* Get the list of SQL statements in the history.
*
* @return the commands
*/
ArrayList<String> getCommands() {
return commandHistory;
}
/**
* Update session meta data information and get the information in a map.
*
* @return a map containing the session meta data
*/
HashMap<String, Object> getInfo() {
HashMap<String, Object> m = New.hashMap();
m.putAll(map);
m.put("lastAccess", new Timestamp(lastAccess).toString());
try {
m.put("url", conn == null ? "${text.admin.notConnected}" : conn.getMetaData().getURL());
m.put("user", conn == null ? "-" : conn.getMetaData().getUserName());
m.put("lastQuery", commandHistory.size() == 0 ? "" : commandHistory.get(0));
m.put("executing", executingStatement == null ? "${text.admin.no}" : "${text.admin.yes}");
} catch (SQLException e) {
TraceSystem.traceThrowable(e);
}
return m;
}
void setConnection(Connection conn) throws SQLException {
this.conn = conn;
if (conn == null) {
meta = null;
} else {
meta = conn.getMetaData();
}
contents = new DbContents();
}
DatabaseMetaData getMetaData() {
return meta;
}
Connection getConnection() {
return conn;
}
DbContents getContents() {
return contents;
}
/**
* Shutdown the server when disconnecting.
*/
void setShutdownServerOnDisconnect() {
this.shutdownServerOnDisconnect = true;
}
boolean getShutdownServerOnDisconnect() {
return shutdownServerOnDisconnect;
}
/**
* Close the connection and stop the statement if one is currently
* executing.
*/
void close() {
if (executingStatement != null) {
try {
executingStatement.cancel();
} catch (Exception e) {
// ignore
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
// ignore
}
}
}
}