1 package net.argius.stew;
3 import static net.argius.stew.Bootstrap.getSystemFile;
10 import net.argius.stew.ui.*;
15 public final class Environment {
17 static final String ALIAS_PROPERTIES_NAME = "alias.properties";
19 private static final Logger log = Logger.getLogger(Environment.class);
20 static ResourceManager res = ResourceManager.getInstance(Environment.class);
22 private OutputProcessor outputProcessor;
23 private ConnectorMap connectorMap;
24 private Connector connector;
25 private Connection conn;
27 private int timeoutSeconds;
28 private File currentDirectory;
29 private long connectorTimestamp;
30 private AliasMap aliasMap;
31 private ScriptContext scriptContext;
33 private Environment(ConnectorMap connectorMap, File currentDirectory) {
34 this.connectorMap = connectorMap;
35 this.currentDirectory = currentDirectory;
37 final File aliasPropFile = getSystemFile(ALIAS_PROPERTIES_NAME);
38 this.aliasMap = new AliasMap(aliasPropFile);
39 if (aliasPropFile.exists()) {
42 } catch (IOException ex) {
51 public Environment() {
52 this(new ConnectorMap(), getInitialCurrentDirectory()); // init directories
53 initializeQueryTimeout();
55 initializeScriptContext();
59 * A constructor (for copy).
62 public Environment(Environment src) {
63 // never copy coconnector,conn,op,aliasMap,scriptContext into this
64 this(new ConnectorMap(src.connectorMap), src.currentDirectory);
65 this.timeoutSeconds = src.timeoutSeconds;
69 * Releases resouces it keeps.
71 public void release() {
74 log.debug("released connection");
75 } catch (SQLException ex) {
76 log.error(ex, "release error");
78 outputProcessor = null;
82 currentDirectory = null;
84 log.debug("released internal state of Environment");
88 * Establishes a connection.
90 * @throws SQLException
92 void establishConnection(Connector connector) throws SQLException {
93 Connection conn = connector.getConnection();
95 if (connector.isReadOnly()) {
96 conn.setReadOnly(true);
98 } catch (RuntimeException ex) {
101 boolean isAutoCommitAvailable;
103 conn.setAutoCommit(false);
104 isAutoCommitAvailable = conn.getAutoCommit();
105 } catch (RuntimeException ex) {
107 isAutoCommitAvailable = false;
109 if (isAutoCommitAvailable) {
110 outputMessage("w.auto-commit-not-available");
112 setCurrentConnection(conn);
113 setCurrentConnector(connector);
114 outputMessage("i.connected");
115 log.debug("connected %s (conn=%08x, env=%08x)", connector.getId(), conn.hashCode(), hashCode());
116 if (Bootstrap.getPropertyAsBoolean("net.argius.stew.print-connected-time")) {
117 outputMessage("i.now", System.currentTimeMillis());
122 * Releases the connection.
123 * @throws SQLException
125 void releaseConnection() throws SQLException {
127 log.debug("not connected");
131 if (connector != null && connector.usesAutoRollback()) {
134 outputMessage("i.rollbacked");
135 log.debug("rollbacked %s (%s)", connector.getId(), conn);
136 } catch (SQLException ex) {
138 Writer w = new StringWriter();
139 PrintWriter out = new PrintWriter(w);
140 ex.printStackTrace(out);
141 outputMessage("e.database", w);
142 outputMessage("w.error-occurred-on-auto-rollback", ex);
147 if (log.isDebugEnabled()) {
148 final String id = (connector == null) ? "null" : connector.getId();
149 log.debug("disconnected %s (conn=%08x, env=%08x)", id, conn.hashCode(), hashCode());
151 if (Bootstrap.getPropertyAsBoolean("net.argius.stew.print-disconnected-time")) {
152 outputMessage("i.now", System.currentTimeMillis());
154 } catch (SQLException ex) {
164 private void outputMessage(String id, Object... args) throws CommandException {
165 if (outputProcessor != null) {
166 outputProcessor.output(res.get(id, args));
170 private static File getInitialCurrentDirectory() {
171 final String propkey = "net.argius.stew.directory";
172 if (Bootstrap.hasProperty(propkey)) {
173 File directory = new File(Bootstrap.getProperty(propkey, ""));
174 if (directory.isDirectory()) {
178 return new File(".");
181 private void initializeQueryTimeout() {
182 this.timeoutSeconds = Bootstrap.getPropertyAsInt("net.argius.stew.query.timeout", -1);
183 if (log.isDebugEnabled()) {
184 log.debug("timeout: " + this.timeoutSeconds);
188 void initializeScriptContext() {
189 this.scriptContext = new SimpleScriptContext();
193 * Loads and refreshes connector map.
195 public void loadConnectorMap() {
198 m = ConnectorConfiguration.load();
199 } catch (IOException ex) {
200 m = new ConnectorMap();
202 synchronized (connectorMap) {
203 if (connectorMap.size() > 0) {
204 connectorMap.clear();
206 connectorMap.putAll(m);
207 connectorTimestamp = ConnectorConfiguration.lastModified();
212 * Updates connector map.
213 * When file was updated, it calls loadConnectorMap().
214 * @return whether updated or not
216 public boolean updateConnectorMap() {
217 if (ConnectorConfiguration.lastModified() > connectorTimestamp) {
224 public OutputProcessor getOutputProcessor() {
225 return outputProcessor;
228 public void setOutputProcessor(OutputProcessor outputProcessor) {
229 this.outputProcessor = outputProcessor;
232 public ConnectorMap getConnectorMap() {
236 public Connector getCurrentConnector() {
240 void setCurrentConnector(Connector connector) {
241 this.connector = connector;
244 public Connection getCurrentConnection() {
248 void setCurrentConnection(Connection conn) {
252 public int getTimeoutSeconds() {
253 return timeoutSeconds;
256 public File getCurrentDirectory() {
257 return currentDirectory;
260 public void setCurrentDirectory(File currentDirectory) {
261 this.currentDirectory = currentDirectory;
265 * @return system directory
266 * @deprecated use Bootstrap.getSystemDirectory() instead
269 public File getSystemDirectory() {
270 return Bootstrap.getSystemDirectory();
273 public AliasMap getAliasMap() {
277 public ScriptContext getScriptContext() {
278 return scriptContext;