https://tree.taiga.io/project/jr-utily-grog-v3/us/195 Mettre en place une connexion h2 via servlet
Showing
7 changed files
with
507 additions
and
0 deletions
1 | +package org.legrog.util; | ||
2 | +// Code copied from org.h2.server.web.ConnectionInfo | ||
3 | +/* | ||
4 | + * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, | ||
5 | + * and the EPL 1.0 (http://h2database.com/html/license.html). | ||
6 | + * Initial Developer: H2 Group | ||
7 | + */ | ||
8 | +//package org.h2.server.web; | ||
9 | + | ||
10 | + import org.h2.util.MathUtils; | ||
11 | + import org.h2.util.StringUtils; | ||
12 | + | ||
13 | +/** | ||
14 | + * The connection info object is a wrapper for database connection information | ||
15 | + * such as the database URL, user name and password. | ||
16 | + * This class is used by the H2 Console. | ||
17 | + */ | ||
18 | +public class ConnectionInfo implements Comparable<ConnectionInfo> { | ||
19 | + /** | ||
20 | + * The driver class name. | ||
21 | + */ | ||
22 | + public String driver; | ||
23 | + | ||
24 | + /** | ||
25 | + * The database URL. | ||
26 | + */ | ||
27 | + public String url; | ||
28 | + | ||
29 | + /** | ||
30 | + * The user name. | ||
31 | + */ | ||
32 | + public String user; | ||
33 | + | ||
34 | + /** | ||
35 | + * The connection display name. | ||
36 | + */ | ||
37 | + String name; | ||
38 | + | ||
39 | + /** | ||
40 | + * The last time this connection was used. | ||
41 | + */ | ||
42 | + int lastAccess; | ||
43 | + | ||
44 | + ConnectionInfo() { | ||
45 | + // nothing to do | ||
46 | + } | ||
47 | + | ||
48 | + public ConnectionInfo(String data) { | ||
49 | + String[] array = StringUtils.arraySplit(data, '|', false); | ||
50 | + name = get(array, 0); | ||
51 | + driver = get(array, 1); | ||
52 | + url = get(array, 2); | ||
53 | + user = get(array, 3); | ||
54 | + } | ||
55 | + | ||
56 | + private static String get(String[] array, int i) { | ||
57 | + return array != null && array.length > i ? array[i] : ""; | ||
58 | + } | ||
59 | + | ||
60 | + String getString() { | ||
61 | + return StringUtils.arrayCombine(new String[] { name, driver, url, user }, '|'); | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
65 | + public int compareTo(ConnectionInfo o) { | ||
66 | + return -MathUtils.compareInt(lastAccess, o.lastAccess); | ||
67 | + } | ||
68 | + | ||
69 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +package org.legrog.util; | ||
2 | + | ||
3 | +import javax.servlet.annotation.WebServlet; | ||
4 | + | ||
5 | +import java.io.IOException; | ||
6 | +import java.net.InetAddress; | ||
7 | +import java.net.UnknownHostException; | ||
8 | +import java.util.ArrayList; | ||
9 | +import java.util.Enumeration; | ||
10 | +import java.util.Properties; | ||
11 | + | ||
12 | +import javax.servlet.ServletConfig; | ||
13 | +import javax.servlet.ServletOutputStream; | ||
14 | +import javax.servlet.http.HttpServlet; | ||
15 | +import javax.servlet.http.HttpServletRequest; | ||
16 | +import javax.servlet.http.HttpServletResponse; | ||
17 | + | ||
18 | +import org.h2.engine.Constants; | ||
19 | +import org.h2.server.web.PageParser; | ||
20 | +import org.h2.util.New; | ||
21 | + | ||
22 | + | ||
23 | +@WebServlet(urlPatterns="/console/*", name="H2Console", loadOnStartup=1) | ||
24 | +public class H2ConsoleServlet extends HttpServlet { | ||
25 | +// Code copied from org.h2.server.web.WebServlet | ||
26 | + private static final long serialVersionUID = 1L; | ||
27 | + private transient WebServer server; | ||
28 | + | ||
29 | + @Override | ||
30 | + public void init() { | ||
31 | + ServletConfig config = getServletConfig(); | ||
32 | + Enumeration<?> en = config.getInitParameterNames(); | ||
33 | + ArrayList<String> list = New.arrayList(); | ||
34 | + while (en.hasMoreElements()) { | ||
35 | + String name = en.nextElement().toString(); | ||
36 | + String value = config.getInitParameter(name); | ||
37 | + if (!name.startsWith("-")) { | ||
38 | + name = "-" + name; | ||
39 | + } | ||
40 | + list.add(name); | ||
41 | + if (value.length() > 0) { | ||
42 | + list.add(value); | ||
43 | + } | ||
44 | + } | ||
45 | + String[] args = new String[list.size()]; | ||
46 | + list.toArray(args); | ||
47 | + server = new WebServer(); | ||
48 | + server.setAllowChunked(false); | ||
49 | + server.init(args); | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public void destroy() { | ||
54 | + server.stop(); | ||
55 | + } | ||
56 | + | ||
57 | + private boolean allow(HttpServletRequest req) { | ||
58 | + if (server.getAllowOthers()) { | ||
59 | + return true; | ||
60 | + } | ||
61 | + String addr = req.getRemoteAddr(); | ||
62 | + try { | ||
63 | + InetAddress address = InetAddress.getByName(addr); | ||
64 | + return address.isLoopbackAddress(); | ||
65 | + } catch (UnknownHostException e) { | ||
66 | + return false; | ||
67 | + } catch (NoClassDefFoundError e) { | ||
68 | + // Google App Engine does not allow java.net.InetAddress | ||
69 | + return false; | ||
70 | + } | ||
71 | + } | ||
72 | + | ||
73 | + private String getAllowedFile(HttpServletRequest req, String requestedFile) { | ||
74 | + if (!allow(req)) { | ||
75 | + return "notAllowed.jsp"; | ||
76 | + } | ||
77 | + if (requestedFile.length() == 0) { | ||
78 | + return "index.do"; | ||
79 | + } | ||
80 | + return requestedFile; | ||
81 | + } | ||
82 | + | ||
83 | + @Override | ||
84 | + public void doGet(HttpServletRequest req, HttpServletResponse resp) | ||
85 | + throws IOException { | ||
86 | + req.setCharacterEncoding("utf-8"); | ||
87 | + String file = req.getPathInfo(); | ||
88 | + if (file == null) { | ||
89 | + resp.sendRedirect(req.getRequestURI() + "/"); | ||
90 | + return; | ||
91 | + } else if (file.startsWith("/")) { | ||
92 | + file = file.substring(1); | ||
93 | + } | ||
94 | + file = getAllowedFile(req, file); | ||
95 | + | ||
96 | + // extract the request attributes | ||
97 | + Properties attributes = new Properties(); | ||
98 | + Enumeration<?> en = req.getAttributeNames(); | ||
99 | + while (en.hasMoreElements()) { | ||
100 | + String name = en.nextElement().toString(); | ||
101 | + String value = req.getAttribute(name).toString(); | ||
102 | + attributes.put(name, value); | ||
103 | + } | ||
104 | + en = req.getParameterNames(); | ||
105 | + while (en.hasMoreElements()) { | ||
106 | + String name = en.nextElement().toString(); | ||
107 | + String value = req.getParameter(name); | ||
108 | + attributes.put(name, value); | ||
109 | + } | ||
110 | + | ||
111 | + WebSession session = null; | ||
112 | + String sessionId = attributes.getProperty("jsessionid"); | ||
113 | + if (sessionId != null) { | ||
114 | + session = server.getSession(sessionId); | ||
115 | + } | ||
116 | + WebApp app = new WebApp(server); | ||
117 | + app.setSession(session, attributes); | ||
118 | + String ifModifiedSince = req.getHeader("if-modified-since"); | ||
119 | + | ||
120 | + String hostAddr = req.getRemoteAddr(); | ||
121 | + file = app.processRequest(file, hostAddr); | ||
122 | + session = app.getSession(); | ||
123 | + | ||
124 | + String mimeType = app.getMimeType(); | ||
125 | + boolean cache = app.getCache(); | ||
126 | + | ||
127 | + if (cache && server.getStartDateTime().equals(ifModifiedSince)) { | ||
128 | + resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); | ||
129 | + return; | ||
130 | + } | ||
131 | + byte[] bytes = server.getFile(file); | ||
132 | + if (bytes == null) { | ||
133 | + resp.sendError(HttpServletResponse.SC_NOT_FOUND); | ||
134 | + bytes = ("File not found: " + file).getBytes(Constants.UTF8); | ||
135 | + } else { | ||
136 | + if (session != null && file.endsWith(".jsp")) { | ||
137 | + String page = new String(bytes, Constants.UTF8); | ||
138 | + page = PageParser.parse(page, session.map); | ||
139 | + bytes = page.getBytes(Constants.UTF8); | ||
140 | + } | ||
141 | + resp.setContentType(mimeType); | ||
142 | + if (!cache) { | ||
143 | + resp.setHeader("Cache-Control", "no-cache"); | ||
144 | + } else { | ||
145 | + resp.setHeader("Cache-Control", "max-age=10"); | ||
146 | + resp.setHeader("Last-Modified", server.getStartDateTime()); | ||
147 | + } | ||
148 | + } | ||
149 | + if (bytes != null) { | ||
150 | + ServletOutputStream out = resp.getOutputStream(); | ||
151 | + out.write(bytes); | ||
152 | + } | ||
153 | + } | ||
154 | + | ||
155 | + @Override | ||
156 | + public void doPost(HttpServletRequest req, HttpServletResponse resp) | ||
157 | + throws IOException { | ||
158 | + doGet(req, resp); | ||
159 | + } | ||
160 | +} |
This diff is collapsed. Click to expand it.
src/main/java/org/legrog/util/WebApp.java
0 → 100644
This diff is collapsed. Click to expand it.
src/main/java/org/legrog/util/WebServer.java
0 → 100644
This diff is collapsed. Click to expand it.
1 | +package org.legrog.util; | ||
2 | +// Code copied from org.h2.server.web.WebSession | ||
3 | +/* | ||
4 | + * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, | ||
5 | + * and the EPL 1.0 (http://h2database.com/html/license.html). | ||
6 | + * Initial Developer: H2 Group | ||
7 | + */ | ||
8 | +///package org.h2.server.web; | ||
9 | + | ||
10 | + import java.sql.Connection; | ||
11 | + import java.sql.DatabaseMetaData; | ||
12 | + import java.sql.ResultSet; | ||
13 | + import java.sql.SQLException; | ||
14 | + import java.sql.Statement; | ||
15 | + import java.sql.Timestamp; | ||
16 | + import java.util.ArrayList; | ||
17 | + import java.util.HashMap; | ||
18 | + import java.util.Locale; | ||
19 | + | ||
20 | + import org.h2.bnf.Bnf; | ||
21 | + import org.h2.bnf.context.DbContents; | ||
22 | + import org.h2.bnf.context.DbContextRule; | ||
23 | + import org.h2.message.DbException; | ||
24 | + import org.h2.util.New; | ||
25 | +import org.h2.server.web.*; | ||
26 | + | ||
27 | +/** | ||
28 | + * The web session keeps all data of a user session. | ||
29 | + * This class is used by the H2 Console. | ||
30 | + */ | ||
31 | +class WebSession { | ||
32 | + | ||
33 | + private static final int MAX_HISTORY = 1000; | ||
34 | + | ||
35 | + /** | ||
36 | + * The last time this client sent a request. | ||
37 | + */ | ||
38 | + long lastAccess; | ||
39 | + | ||
40 | + /** | ||
41 | + * The session attribute map. | ||
42 | + */ | ||
43 | + final HashMap<String, Object> map = New.hashMap(); | ||
44 | + | ||
45 | + /** | ||
46 | + * The current locale. | ||
47 | + */ | ||
48 | + Locale locale; | ||
49 | + | ||
50 | + /** | ||
51 | + * The currently executing statement. | ||
52 | + */ | ||
53 | + Statement executingStatement; | ||
54 | + | ||
55 | + /** | ||
56 | + * The current updatable result set. | ||
57 | + */ | ||
58 | + ResultSet result; | ||
59 | + | ||
60 | + private final WebServer server; | ||
61 | + | ||
62 | + private final ArrayList<String> commandHistory; | ||
63 | + | ||
64 | + private Connection conn; | ||
65 | + private DatabaseMetaData meta; | ||
66 | + private DbContents contents = new DbContents(); | ||
67 | + private Bnf bnf; | ||
68 | + private boolean shutdownServerOnDisconnect; | ||
69 | + | ||
70 | + WebSession(WebServer server) { | ||
71 | + this.server = server; | ||
72 | + // This must be stored in the session rather than in the server. | ||
73 | + // Otherwise, one client could allow | ||
74 | + // saving history for others (insecure). | ||
75 | + this.commandHistory = server.getCommandHistoryList(); | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * Put an attribute value in the map. | ||
80 | + * | ||
81 | + * @param key the key | ||
82 | + * @param value the new value | ||
83 | + */ | ||
84 | + void put(String key, Object value) { | ||
85 | + map.put(key, value); | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
89 | + * Get the value for the given key. | ||
90 | + * | ||
91 | + * @param key the key | ||
92 | + * @return the value | ||
93 | + */ | ||
94 | + Object get(String key) { | ||
95 | + if ("sessions".equals(key)) { | ||
96 | + return server.getSessions(); | ||
97 | + } | ||
98 | + return map.get(key); | ||
99 | + } | ||
100 | + | ||
101 | + /** | ||
102 | + * Remove a session attribute from the map. | ||
103 | + * | ||
104 | + * @param key the key | ||
105 | + */ | ||
106 | + void remove(String key) { | ||
107 | + map.remove(key); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * Get the BNF object. | ||
112 | + * | ||
113 | + * @return the BNF object | ||
114 | + */ | ||
115 | + Bnf getBnf() { | ||
116 | + return bnf; | ||
117 | + } | ||
118 | + | ||
119 | + /** | ||
120 | + * Load the SQL grammar BNF. | ||
121 | + */ | ||
122 | + void loadBnf() { | ||
123 | + try { | ||
124 | + Bnf newBnf = Bnf.getInstance(null); | ||
125 | + DbContextRule columnRule = | ||
126 | + new DbContextRule(contents, DbContextRule.COLUMN); | ||
127 | + DbContextRule newAliasRule = | ||
128 | + new DbContextRule(contents, DbContextRule.NEW_TABLE_ALIAS); | ||
129 | + DbContextRule aliasRule = | ||
130 | + new DbContextRule(contents, DbContextRule.TABLE_ALIAS); | ||
131 | + DbContextRule tableRule = | ||
132 | + new DbContextRule(contents, DbContextRule.TABLE); | ||
133 | + DbContextRule schemaRule = | ||
134 | + new DbContextRule(contents, DbContextRule.SCHEMA); | ||
135 | + DbContextRule columnAliasRule = | ||
136 | + new DbContextRule(contents, DbContextRule.COLUMN_ALIAS); | ||
137 | + DbContextRule procedure = | ||
138 | + new DbContextRule(contents, DbContextRule.PROCEDURE); | ||
139 | + newBnf.updateTopic("procedure", procedure); | ||
140 | + newBnf.updateTopic("column_name", columnRule); | ||
141 | + newBnf.updateTopic("new_table_alias", newAliasRule); | ||
142 | + newBnf.updateTopic("table_alias", aliasRule); | ||
143 | + newBnf.updateTopic("column_alias", columnAliasRule); | ||
144 | + newBnf.updateTopic("table_name", tableRule); | ||
145 | + newBnf.updateTopic("schema_name", schemaRule); | ||
146 | + newBnf.linkStatements(); | ||
147 | + bnf = newBnf; | ||
148 | + } catch (Exception e) { | ||
149 | + // ok we don't have the bnf | ||
150 | + server.traceError(e); | ||
151 | + } | ||
152 | + } | ||
153 | + | ||
154 | + /** | ||
155 | + * Get the SQL statement from history. | ||
156 | + * | ||
157 | + * @param id the history id | ||
158 | + * @return the SQL statement | ||
159 | + */ | ||
160 | + String getCommand(int id) { | ||
161 | + return commandHistory.get(id); | ||
162 | + } | ||
163 | + | ||
164 | + /** | ||
165 | + * Add a SQL statement to the history. | ||
166 | + * | ||
167 | + * @param sql the SQL statement | ||
168 | + */ | ||
169 | + void addCommand(String sql) { | ||
170 | + if (sql == null) { | ||
171 | + return; | ||
172 | + } | ||
173 | + sql = sql.trim(); | ||
174 | + if (sql.length() == 0) { | ||
175 | + return; | ||
176 | + } | ||
177 | + if (commandHistory.size() > MAX_HISTORY) { | ||
178 | + commandHistory.remove(0); | ||
179 | + } | ||
180 | + int idx = commandHistory.indexOf(sql); | ||
181 | + if (idx >= 0) { | ||
182 | + commandHistory.remove(idx); | ||
183 | + } | ||
184 | + commandHistory.add(sql); | ||
185 | + if (server.isCommandHistoryAllowed()) { | ||
186 | + server.saveCommandHistoryList(commandHistory); | ||
187 | + } | ||
188 | + } | ||
189 | + | ||
190 | + /** | ||
191 | + * Get the list of SQL statements in the history. | ||
192 | + * | ||
193 | + * @return the commands | ||
194 | + */ | ||
195 | + ArrayList<String> getCommandHistory() { | ||
196 | + return commandHistory; | ||
197 | + } | ||
198 | + | ||
199 | + /** | ||
200 | + * Update session meta data information and get the information in a map. | ||
201 | + * | ||
202 | + * @return a map containing the session meta data | ||
203 | + */ | ||
204 | + HashMap<String, Object> getInfo() { | ||
205 | + HashMap<String, Object> m = New.hashMap(); | ||
206 | + m.putAll(map); | ||
207 | + m.put("lastAccess", new Timestamp(lastAccess).toString()); | ||
208 | + try { | ||
209 | + m.put("url", conn == null ? | ||
210 | + "${text.admin.notConnected}" : conn.getMetaData().getURL()); | ||
211 | + m.put("user", conn == null ? | ||
212 | + "-" : conn.getMetaData().getUserName()); | ||
213 | + m.put("lastQuery", commandHistory.size() == 0 ? | ||
214 | + "" : commandHistory.get(0)); | ||
215 | + m.put("executing", executingStatement == null ? | ||
216 | + "${text.admin.no}" : "${text.admin.yes}"); | ||
217 | + } catch (SQLException e) { | ||
218 | + DbException.traceThrowable(e); | ||
219 | + } | ||
220 | + return m; | ||
221 | + } | ||
222 | + | ||
223 | + void setConnection(Connection conn) throws SQLException { | ||
224 | + this.conn = conn; | ||
225 | + if (conn == null) { | ||
226 | + meta = null; | ||
227 | + } else { | ||
228 | + meta = conn.getMetaData(); | ||
229 | + } | ||
230 | + contents = new DbContents(); | ||
231 | + } | ||
232 | + | ||
233 | + DatabaseMetaData getMetaData() { | ||
234 | + return meta; | ||
235 | + } | ||
236 | + | ||
237 | + Connection getConnection() { | ||
238 | + return conn; | ||
239 | + } | ||
240 | + | ||
241 | + DbContents getContents() { | ||
242 | + return contents; | ||
243 | + } | ||
244 | + | ||
245 | + /** | ||
246 | + * Shutdown the server when disconnecting. | ||
247 | + */ | ||
248 | + void setShutdownServerOnDisconnect() { | ||
249 | + this.shutdownServerOnDisconnect = true; | ||
250 | + } | ||
251 | + | ||
252 | + boolean getShutdownServerOnDisconnect() { | ||
253 | + return shutdownServerOnDisconnect; | ||
254 | + } | ||
255 | + | ||
256 | + /** | ||
257 | + * Close the connection and stop the statement if one is currently | ||
258 | + * executing. | ||
259 | + */ | ||
260 | + void close() { | ||
261 | + if (executingStatement != null) { | ||
262 | + try { | ||
263 | + executingStatement.cancel(); | ||
264 | + } catch (Exception e) { | ||
265 | + // ignore | ||
266 | + } | ||
267 | + } | ||
268 | + if (conn != null) { | ||
269 | + try { | ||
270 | + conn.close(); | ||
271 | + } catch (Exception e) { | ||
272 | + // ignore | ||
273 | + } | ||
274 | + } | ||
275 | + | ||
276 | + } | ||
277 | + | ||
278 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/main/java/org/legrog/util/WebThread.java
0 → 100644
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment