OSDN Git Service

refactoring: functions related to system directory
[stew/Stew4.git] / src / net / argius / stew / Environment.java
1 package net.argius.stew;
2
3 import static net.argius.stew.Bootstrap.getSystemFile;
4
5 import java.io.*;
6 import java.sql.*;
7
8 import net.argius.stew.ui.*;
9
10 /**
11  * Environment.
12  */
13 public final class Environment {
14
15     static final String ALIAS_PROPERTIES_NAME = "alias.properties";
16
17     private static final Logger log = Logger.getLogger(Environment.class);
18     static ResourceManager res = ResourceManager.getInstance(Environment.class);
19
20     private OutputProcessor outputProcessor;
21     private ConnectorMap connectorMap;
22     private Connector connector;
23     private Connection conn;
24
25     private int timeoutSeconds;
26     private File currentDirectory;
27     private long connectorTimestamp;
28     private AliasMap aliasMap;
29
30     /**
31      * A constructor.
32      */
33     public Environment() {
34         initializeQueryTimeout();
35         // init connections
36         this.connectorMap = new ConnectorMap();
37         loadConnectorMap();
38         // init directories
39         this.currentDirectory = getInitialCurrentDirectory();
40         // init alias
41         final File aliasPropFile = getSystemFile(ALIAS_PROPERTIES_NAME);
42         this.aliasMap = new AliasMap(aliasPropFile);
43         if (aliasPropFile.exists()) {
44             try {
45                 aliasMap.load();
46             } catch (IOException ex) {
47                 log.warn(ex);
48             }
49         }
50     }
51
52     /**
53      * A constructor (for copy).
54      * @param src
55      */
56     public Environment(Environment src) {
57         // never copy coconnector,conn,op into this
58         this.connectorMap = new ConnectorMap(src.connectorMap);
59         this.timeoutSeconds = src.timeoutSeconds;
60         this.currentDirectory = src.currentDirectory;
61     }
62
63     /**
64      * Releases resouces it keeps.
65      */
66     public void release() {
67         try {
68             releaseConnection();
69             log.debug("released connection");
70         } catch (SQLException ex) {
71             log.error(ex, "release error");
72         } finally {
73             outputProcessor = null;
74             connectorMap = null;
75             connector = null;
76             conn = null;
77             currentDirectory = null;
78         }
79         log.debug("released internal state of Environment");
80     }
81
82     /**
83      * Establishes a connection.
84      * @param connector
85      * @throws SQLException
86      */
87     void establishConnection(Connector connector) throws SQLException {
88         Connection conn = connector.getConnection();
89         try {
90             if (connector.isReadOnly()) {
91                 conn.setReadOnly(true);
92             }
93         } catch (RuntimeException ex) {
94             log.warn(ex);
95         }
96         boolean isAutoCommitAvailable;
97         try {
98             conn.setAutoCommit(false);
99             isAutoCommitAvailable = conn.getAutoCommit();
100         } catch (RuntimeException ex) {
101             log.warn(ex);
102             isAutoCommitAvailable = false;
103         }
104         if (isAutoCommitAvailable) {
105             outputMessage("w.auto-commit-not-available");
106         }
107         setCurrentConnection(conn);
108         setCurrentConnector(connector);
109         outputMessage("i.connected");
110         log.debug("connected %s (conn=%08x, env=%08x)", connector.getId(), conn.hashCode(), hashCode());
111         if (Bootstrap.getPropertyAsBoolean("net.argius.stew.print-connected-time")) {
112             outputMessage("i.now", System.currentTimeMillis());
113         }
114     }
115
116     /**
117      * Releases the connection.
118      * @throws SQLException
119      */
120     void releaseConnection() throws SQLException {
121         if (conn == null) {
122             log.debug("not connected");
123             return;
124         }
125         try {
126             if (connector != null && connector.usesAutoRollback()) {
127                 try {
128                     conn.rollback();
129                     outputMessage("i.rollbacked");
130                     log.debug("rollbacked %s (%s)", connector.getId(), conn);
131                 } catch (SQLException ex) {
132                     log.warn(ex);
133                     Writer w = new StringWriter();
134                     PrintWriter out = new PrintWriter(w);
135                     ex.printStackTrace(out);
136                     outputMessage("e.database", w);
137                     outputMessage("w.error-occurred-on-auto-rollback", ex);
138                 }
139             }
140             try {
141                 conn.close();
142                 log.debug("disconnected %s (conn=%08x, env=%08x)", connector.getId(), conn.hashCode(), hashCode());
143                 if (Bootstrap.getPropertyAsBoolean("net.argius.stew.print-disconnected-time")) {
144                     outputMessage("i.now", System.currentTimeMillis());
145                 }
146             } catch (SQLException ex) {
147                 log.warn(ex);
148                 throw ex;
149             }
150         } finally {
151             conn = null;
152             connector = null;
153         }
154     }
155
156     private void outputMessage(String id, Object... args) throws CommandException {
157         if (outputProcessor != null) {
158             outputProcessor.output(res.get(id, args));
159         }
160     }
161
162     private static File getInitialCurrentDirectory() {
163         final String propkey = "net.argius.stew.directory";
164         if (Bootstrap.hasProperty(propkey)) {
165             File directory = new File(Bootstrap.getProperty(propkey, ""));
166             if (directory.isDirectory()) {
167                 return directory;
168             }
169         }
170         return new File(".");
171     }
172
173     private void initializeQueryTimeout() {
174         this.timeoutSeconds = Bootstrap.getPropertyAsInt("net.argius.stew.query.timeout", -1);
175         if (log.isDebugEnabled()) {
176             log.debug("timeout: " + this.timeoutSeconds);
177         }
178     }
179
180     /**
181      * Loads and refreshes connector map.
182      */
183     public void loadConnectorMap() {
184         ConnectorMap m;
185         try {
186             m = ConnectorConfiguration.load();
187         } catch (IOException ex) {
188             m = new ConnectorMap();
189         }
190         synchronized (connectorMap) {
191             if (connectorMap.size() > 0) {
192                 connectorMap.clear();
193             }
194             connectorMap.putAll(m);
195             connectorTimestamp = ConnectorConfiguration.lastModified();
196         }
197     }
198
199     /**
200      * Updates connector map.
201      * When file was updated, it calls loadConnectorMap().
202      * @return whether updated or not
203      */
204     public boolean updateConnectorMap() {
205         if (ConnectorConfiguration.lastModified() > connectorTimestamp) {
206             loadConnectorMap();
207             return true;
208         }
209         return false;
210     }
211
212     public OutputProcessor getOutputProcessor() {
213         return outputProcessor;
214     }
215
216     public void setOutputProcessor(OutputProcessor outputProcessor) {
217         this.outputProcessor = outputProcessor;
218     }
219
220     public ConnectorMap getConnectorMap() {
221         return connectorMap;
222     }
223
224     public Connector getCurrentConnector() {
225         return connector;
226     }
227
228     void setCurrentConnector(Connector connector) {
229         this.connector = connector;
230     }
231
232     public Connection getCurrentConnection() {
233         return conn;
234     }
235
236     void setCurrentConnection(Connection conn) {
237         this.conn = conn;
238     }
239
240     public int getTimeoutSeconds() {
241         return timeoutSeconds;
242     }
243
244     public File getCurrentDirectory() {
245         return currentDirectory;
246     }
247
248     public void setCurrentDirectory(File currentDirectory) {
249         this.currentDirectory = currentDirectory;
250     }
251
252     /**
253      * @return system directory
254      * @deprecated use Bootstrap.getSystemDirectory() instead
255      */
256     @Deprecated
257     public File getSystemDirectory() {
258         return Bootstrap.getSystemDirectory();
259     }
260
261     public AliasMap getAliasMap() {
262         return aliasMap;
263     }
264
265 }