Source Code Cross Referenced for WebThread.java in  » Database-DBMS » h2database » org » h2 » server » web » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » h2database » org.h2.server.web 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
0003:         * (http://h2database.com/html/license.html).
0004:         * Initial Developer: H2 Group
0005:         */
0006:        package org.h2.server.web;
0007:
0008:        import java.io.BufferedInputStream;
0009:        import java.io.BufferedOutputStream;
0010:        import java.io.DataInputStream;
0011:        import java.io.File;
0012:        import java.io.FileInputStream;
0013:        import java.io.FileWriter;
0014:        import java.io.IOException;
0015:        import java.io.InputStream;
0016:        import java.io.OutputStream;
0017:        import java.io.PrintWriter;
0018:        import java.io.StringReader;
0019:        import java.io.StringWriter;
0020:        import java.lang.reflect.Method;
0021:        import java.net.MalformedURLException;
0022:        import java.net.Socket;
0023:        import java.security.SecureClassLoader;
0024:        import java.sql.Connection;
0025:        import java.sql.DatabaseMetaData;
0026:        import java.sql.ParameterMetaData;
0027:        import java.sql.PreparedStatement;
0028:        import java.sql.ResultSet;
0029:        import java.sql.ResultSetMetaData;
0030:        import java.sql.SQLException;
0031:        import java.sql.Statement;
0032:        import java.sql.Types;
0033:        import java.text.SimpleDateFormat;
0034:        import java.util.ArrayList;
0035:        import java.util.Collections;
0036:        import java.util.Date;
0037:        import java.util.HashMap;
0038:        import java.util.Iterator;
0039:        import java.util.Locale;
0040:        import java.util.Map;
0041:        import java.util.Properties;
0042:        import java.util.Random;
0043:        import java.util.StringTokenizer;
0044:        import java.util.Map.Entry;
0045:
0046:        import org.h2.api.DatabaseEventListener;
0047:        import org.h2.bnf.Bnf;
0048:        import org.h2.constant.ErrorCode;
0049:        import org.h2.engine.Constants;
0050:        import org.h2.jdbc.JdbcSQLException;
0051:        import org.h2.message.TraceSystem;
0052:        import org.h2.tools.SimpleResultSet;
0053:        import org.h2.util.IOUtils;
0054:        import org.h2.util.JdbcUtils;
0055:        import org.h2.util.MathUtils;
0056:        import org.h2.util.MemoryUtils;
0057:        import org.h2.util.NetUtils;
0058:        import org.h2.util.ObjectArray;
0059:        import org.h2.util.ObjectUtils;
0060:        import org.h2.util.ScriptReader;
0061:        import org.h2.util.StringUtils;
0062:
0063:        /**
0064:         * For each connection to a session, an object of this class is created.
0065:         * This class is used by the H2 Console.
0066:         */
0067:        class WebThread extends Thread implements  DatabaseEventListener {
0068:            private WebServer server;
0069:            private WebSession session;
0070:            private Properties attributes;
0071:            private Socket socket;
0072:
0073:            private InputStream input;
0074:            private OutputStream output;
0075:            private String ifModifiedSince;
0076:            private String mimeType;
0077:            private boolean cache;
0078:            private int listenerLastState;
0079:            private long listenerLastEvent;
0080:            private boolean stop;
0081:
0082:            // TODO web: support online data editing like http://numsum.com/
0083:
0084:            WebThread(Socket socket, WebServer server) {
0085:                this .server = server;
0086:                this .socket = socket;
0087:                setName("H2 Console thread");
0088:            }
0089:
0090:            void setSession(WebSession session, Properties attributes) {
0091:                this .session = session;
0092:                this .attributes = attributes;
0093:            }
0094:
0095:            public void stopNow() {
0096:                this .stop = true;
0097:            }
0098:
0099:            private String getAllowedFile(String requestedFile) {
0100:                if (!allow()) {
0101:                    return "notAllowed.jsp";
0102:                }
0103:                if (requestedFile.length() == 0) {
0104:                    return "index.do";
0105:                }
0106:                return requestedFile;
0107:            }
0108:
0109:            public String processRequest(String file, String hostAddr) {
0110:                int index = file.lastIndexOf('.');
0111:                String suffix;
0112:                if (index >= 0) {
0113:                    suffix = file.substring(index + 1);
0114:                } else {
0115:                    suffix = "";
0116:                }
0117:                if ("ico".equals(suffix)) {
0118:                    mimeType = "image/x-icon";
0119:                    cache = true;
0120:                } else if ("gif".equals(suffix)) {
0121:                    mimeType = "image/gif";
0122:                    cache = true;
0123:                } else if ("css".equals(suffix)) {
0124:                    cache = true;
0125:                    mimeType = "text/css";
0126:                } else if ("html".equals(suffix) || "do".equals(suffix)
0127:                        || "jsp".equals(suffix)) {
0128:                    cache = false;
0129:                    mimeType = "text/html";
0130:                    if (session == null) {
0131:                        session = server.createNewSession(hostAddr);
0132:                        if (!"notAllowed.jsp".equals(file)) {
0133:                            file = "index.do";
0134:                        }
0135:                    }
0136:                } else if ("js".equals(suffix)) {
0137:                    cache = true;
0138:                    mimeType = "text/javascript";
0139:                } else {
0140:                    cache = false;
0141:                    mimeType = "text/html";
0142:                    file = "error.jsp";
0143:                    server.trace("unknown mime type, file " + file);
0144:                }
0145:                server.trace("mimeType=" + mimeType);
0146:                server.trace(file);
0147:                if (file.endsWith(".do")) {
0148:                    file = process(file);
0149:                }
0150:                return file;
0151:            }
0152:
0153:            public void run() {
0154:                try {
0155:                    input = new BufferedInputStream(socket.getInputStream());
0156:                    output = new BufferedOutputStream(socket.getOutputStream());
0157:                    while (true) {
0158:                        if (!process()) {
0159:                            break;
0160:                        }
0161:                    }
0162:                } catch (IOException e) {
0163:                    TraceSystem.traceThrowable(e);
0164:                } catch (SQLException e) {
0165:                    TraceSystem.traceThrowable(e);
0166:                }
0167:                IOUtils.closeSilently(output);
0168:                IOUtils.closeSilently(input);
0169:                try {
0170:                    socket.close();
0171:                } catch (IOException e) {
0172:                    // ignore
0173:                } finally {
0174:                    server.remove(this );
0175:                }
0176:            }
0177:
0178:            public boolean process() throws IOException, SQLException {
0179:                boolean keepAlive = false;
0180:                String head = readHeaderLine();
0181:                if (head.startsWith("GET ") || head.startsWith("POST ")) {
0182:                    int begin = head.indexOf('/'), end = head.lastIndexOf(' ');
0183:                    String file = head.substring(begin + 1, end).trim();
0184:                    server.trace(head + ": " + file);
0185:                    file = getAllowedFile(file);
0186:                    attributes = new Properties();
0187:                    int paramIndex = file.indexOf("?");
0188:                    session = null;
0189:                    if (paramIndex >= 0) {
0190:                        String attrib = file.substring(paramIndex + 1);
0191:                        parseAttributes(attrib);
0192:                        String sessionId = attributes.getProperty("jsessionid");
0193:                        file = file.substring(0, paramIndex);
0194:                        session = server.getSession(sessionId);
0195:                    }
0196:                    keepAlive = parseHeader();
0197:                    String hostAddr = socket.getInetAddress().getHostAddress();
0198:                    file = processRequest(file, hostAddr);
0199:                    if (file.length() == 0) {
0200:                        // asynchronous request
0201:                        return true;
0202:                    }
0203:                    String message;
0204:                    byte[] bytes;
0205:                    if (cache
0206:                            && ifModifiedSince != null
0207:                            && ifModifiedSince
0208:                                    .equals(server.getStartDateTime())) {
0209:                        bytes = null;
0210:                        message = "HTTP/1.1 304 Not Modified\n";
0211:                    } else {
0212:                        bytes = server.getFile(file);
0213:                        if (bytes == null) {
0214:                            message = "HTTP/1.0 404 Not Found\n";
0215:                            bytes = StringUtils.utf8Encode("File not found: "
0216:                                    + file);
0217:                        } else {
0218:                            if (session != null && file.endsWith(".jsp")) {
0219:                                String page = StringUtils.utf8Decode(bytes);
0220:                                page = PageParser.parse(server, page,
0221:                                        session.map);
0222:                                try {
0223:                                    bytes = StringUtils.utf8Encode(page);
0224:                                } catch (SQLException e) {
0225:                                    server.traceError(e);
0226:                                }
0227:                            }
0228:                            message = "HTTP/1.1 200 OK\n";
0229:                            message += "Content-Type: " + mimeType + "\n";
0230:                            if (!cache) {
0231:                                message += "Cache-Control: no-cache\n";
0232:                            } else {
0233:                                message += "Cache-Control: max-age=10\n";
0234:                                message += "Last-Modified: "
0235:                                        + server.getStartDateTime() + "\n";
0236:                            }
0237:                            message += "Content-Length: " + bytes.length + "\n";
0238:                        }
0239:                    }
0240:                    message += "\n";
0241:                    server.trace(message);
0242:                    output.write(message.getBytes());
0243:                    if (bytes != null) {
0244:                        output.write(bytes);
0245:                    }
0246:                    output.flush();
0247:                }
0248:                return keepAlive;
0249:            }
0250:
0251:            protected String getComboBox(String[] elements, String selected) {
0252:                StringBuffer buff = new StringBuffer();
0253:                for (int i = 0; i < elements.length; i++) {
0254:                    String value = elements[i];
0255:                    buff.append("<option value=\"");
0256:                    buff.append(PageParser.escapeHtmlData(value));
0257:                    buff.append("\"");
0258:                    if (value.equals(selected)) {
0259:                        buff.append(" selected");
0260:                    }
0261:                    buff.append(">");
0262:                    buff.append(PageParser.escapeHtml(value));
0263:                    buff.append("</option>");
0264:                }
0265:                return buff.toString();
0266:            }
0267:
0268:            protected String getComboBox(String[][] elements, String selected) {
0269:                StringBuffer buff = new StringBuffer();
0270:                for (int i = 0; i < elements.length; i++) {
0271:                    String[] n = elements[i];
0272:                    buff.append("<option value=\"");
0273:                    buff.append(PageParser.escapeHtmlData(n[0]));
0274:                    buff.append("\"");
0275:                    if (n[0].equals(selected)) {
0276:                        buff.append(" selected");
0277:                    }
0278:                    buff.append(">");
0279:                    buff.append(PageParser.escapeHtml(n[1]));
0280:                    buff.append("</option>");
0281:                }
0282:                return buff.toString();
0283:            }
0284:
0285:            private String readHeaderLine() throws IOException {
0286:                StringBuffer buff = new StringBuffer();
0287:                while (true) {
0288:                    int i = input.read();
0289:                    if (i == -1) {
0290:                        throw new IOException("Unexpected EOF");
0291:                    } else if (i == '\r' && input.read() == '\n') {
0292:                        return buff.length() > 0 ? buff.toString() : null;
0293:                    } else {
0294:                        buff.append((char) i);
0295:                    }
0296:                }
0297:            }
0298:
0299:            private void parseAttributes(String s) throws SQLException {
0300:                server.trace("data=" + s);
0301:                while (s != null) {
0302:                    int idx = s.indexOf('=');
0303:                    if (idx >= 0) {
0304:                        String property = s.substring(0, idx);
0305:                        s = s.substring(idx + 1);
0306:                        idx = s.indexOf('&');
0307:                        String value;
0308:                        if (idx >= 0) {
0309:                            value = s.substring(0, idx);
0310:                            s = s.substring(idx + 1);
0311:                        } else {
0312:                            value = s;
0313:                        }
0314:                        // TODO compatibility problem with JDK 1.3
0315:                        // String attr = URLDecoder.decode(value, "UTF-8");
0316:                        // String attr = URLDecoder.decode(value);
0317:                        String attr = StringUtils.urlDecode(value);
0318:                        attributes.put(property, attr);
0319:                    } else {
0320:                        break;
0321:                    }
0322:                }
0323:                server.trace(attributes.toString());
0324:            }
0325:
0326:            private boolean parseHeader() throws IOException, SQLException {
0327:                boolean keepAlive = false;
0328:                server.trace("parseHeader");
0329:                int len = 0;
0330:                ifModifiedSince = null;
0331:                while (true) {
0332:                    String line = readHeaderLine();
0333:                    if (line == null) {
0334:                        break;
0335:                    }
0336:                    server.trace(" " + line);
0337:                    String lower = StringUtils.toLowerEnglish(line);
0338:                    if (lower.startsWith("if-modified-since")) {
0339:                        ifModifiedSince = line.substring(line.indexOf(':') + 1)
0340:                                .trim();
0341:                    } else if (lower.startsWith("connection")) {
0342:                        String conn = line.substring(line.indexOf(':') + 1)
0343:                                .trim();
0344:                        if ("keep-alive".equals(conn)) {
0345:                            keepAlive = true;
0346:                        }
0347:                    } else if (lower.startsWith("content-length")) {
0348:                        len = Integer.parseInt(line.substring(
0349:                                line.indexOf(':') + 1).trim());
0350:                        server.trace("len=" + len);
0351:                    } else if (lower.startsWith("accept-language")) {
0352:                        if (session != null) {
0353:                            Locale locale = session.locale;
0354:                            if (locale == null) {
0355:                                String languages = line.substring(
0356:                                        line.indexOf(':') + 1).trim();
0357:                                StringTokenizer tokenizer = new StringTokenizer(
0358:                                        languages, ",;");
0359:                                while (tokenizer.hasMoreTokens()) {
0360:                                    String token = tokenizer.nextToken();
0361:                                    if (!token.startsWith("q=")) {
0362:                                        if (server.supportsLanguage(token)) {
0363:                                            int dash = token.indexOf('-');
0364:                                            if (dash >= 0) {
0365:                                                String language = token
0366:                                                        .substring(0, dash);
0367:                                                String country = token
0368:                                                        .substring(dash + 1);
0369:                                                locale = new Locale(language,
0370:                                                        country);
0371:                                            } else {
0372:                                                locale = new Locale(token, "");
0373:                                            }
0374:                                            session.locale = locale;
0375:                                            String language = locale
0376:                                                    .getLanguage();
0377:                                            session.put("language", language);
0378:                                            server.readTranslations(session,
0379:                                                    language);
0380:                                            break;
0381:                                        }
0382:                                    }
0383:                                }
0384:                            }
0385:                        }
0386:                    } else if (line.trim().length() == 0) {
0387:                        break;
0388:                    }
0389:                }
0390:                if (session != null && len > 0) {
0391:                    byte[] bytes = new byte[len];
0392:                    for (int pos = 0; pos < len;) {
0393:                        pos += input.read(bytes, pos, len - pos);
0394:                    }
0395:                    String s = new String(bytes);
0396:                    parseAttributes(s);
0397:                }
0398:                return keepAlive;
0399:            }
0400:
0401:            String process(String file) {
0402:                server.trace("process " + file);
0403:                while (file.endsWith(".do")) {
0404:                    if ("login.do".equals(file)) {
0405:                        file = login();
0406:                    } else if ("index.do".equals(file)) {
0407:                        file = index();
0408:                    } else if ("logout.do".equals(file)) {
0409:                        file = logout();
0410:                    } else if ("settingRemove.do".equals(file)) {
0411:                        file = settingRemove();
0412:                    } else if ("settingSave.do".equals(file)) {
0413:                        file = settingSave();
0414:                    } else if ("test.do".equals(file)) {
0415:                        file = test();
0416:                    } else if ("query.do".equals(file)) {
0417:                        file = query();
0418:                    } else if ("tables.do".equals(file)) {
0419:                        file = tables();
0420:                    } else if ("editResult.do".equals(file)) {
0421:                        file = editResult();
0422:                    } else if ("getHistory.do".equals(file)) {
0423:                        file = getHistory();
0424:                    } else if ("admin.do".equals(file)) {
0425:                        file = admin();
0426:                    } else if ("adminSave.do".equals(file)) {
0427:                        file = adminSave();
0428:                    } else if ("adminShutdown.do".equals(file)) {
0429:                        file = adminShutdown();
0430:                    } else if ("autoCompleteList.do".equals(file)) {
0431:                        file = autoCompleteList();
0432:                    } else {
0433:                        file = "error.jsp";
0434:                    }
0435:                }
0436:                server.trace("return " + file);
0437:                return file;
0438:            }
0439:
0440:            private String autoCompleteList() {
0441:                String query = (String) attributes.get("query");
0442:                boolean lowercase = false;
0443:                if (query.trim().length() > 0
0444:                        && Character.isLowerCase(query.trim().charAt(0))) {
0445:                    lowercase = true;
0446:                }
0447:                try {
0448:                    String sql = query;
0449:                    if (sql.endsWith(";")) {
0450:                        sql += " ";
0451:                    }
0452:                    ScriptReader reader = new ScriptReader(
0453:                            new StringReader(sql));
0454:                    reader.setSkipRemarks(true);
0455:                    String lastSql = "";
0456:                    while (true) {
0457:                        String n = reader.readStatement();
0458:                        if (n == null) {
0459:                            break;
0460:                        }
0461:                        lastSql = n;
0462:                    }
0463:                    String result = "";
0464:                    if (reader.isInsideRemark()) {
0465:                        if (reader.isBlockRemark()) {
0466:                            result = "1#(End Remark)# */\n" + result;
0467:                        } else {
0468:                            result = "1#(Newline)#\n" + result;
0469:                        }
0470:                    } else {
0471:                        sql = lastSql == null ? "" : lastSql;
0472:                        while (sql.length() > 0 && sql.charAt(0) <= ' ') {
0473:                            sql = sql.substring(1);
0474:                        }
0475:                        if (sql.trim().length() > 0
0476:                                && Character.isLowerCase(sql.trim().charAt(0))) {
0477:                            lowercase = true;
0478:                        }
0479:                        Bnf bnf = session.getBnf();
0480:                        if (bnf == null) {
0481:                            return "autoCompleteList.jsp";
0482:                        }
0483:                        HashMap map = bnf.getNextTokenList(sql);
0484:                        String space = "";
0485:                        if (sql.length() > 0) {
0486:                            char last = sql.charAt(sql.length() - 1);
0487:                            if (!Character.isWhitespace(last)
0488:                                    && (last != '.' && last >= ' '
0489:                                            && last != '\'' && last != '"')) {
0490:                                space = " ";
0491:                            }
0492:                        }
0493:                        ArrayList list = new ArrayList(map.size());
0494:                        Iterator it = map.entrySet().iterator();
0495:                        while (it.hasNext()) {
0496:                            Map.Entry entry = (Entry) it.next();
0497:                            String key = (String) entry.getKey();
0498:                            String type = "" + key.charAt(0);
0499:                            String value = (String) entry.getValue();
0500:                            key = key.substring(2);
0501:                            if (Character.isLetter(key.charAt(0)) && lowercase) {
0502:                                key = StringUtils.toLowerEnglish(key);
0503:                                value = StringUtils.toLowerEnglish(value);
0504:                            }
0505:                            if (key.equals(value) && !".".equals(value)) {
0506:                                value = space + value;
0507:                            }
0508:                            key = StringUtils.urlEncode(key);
0509:                            key = StringUtils.replaceAll(key, "+", " ");
0510:                            value = StringUtils.urlEncode(value);
0511:                            value = StringUtils.replaceAll(value, "+", " ");
0512:                            list.add(type + "#" + key + "#" + value);
0513:                        }
0514:                        Collections.sort(list);
0515:                        StringBuffer buff = new StringBuffer();
0516:                        if (query.endsWith("\n") || query.trim().endsWith(";")) {
0517:                            list.add(0, "1#(Newline)#\n");
0518:                        }
0519:                        for (int i = 0; i < list.size(); i++) {
0520:                            if (i > 0) {
0521:                                buff.append('|');
0522:                            }
0523:                            buff.append((String) list.get(i));
0524:                        }
0525:                        result = buff.toString();
0526:                    }
0527:                    session.put("autoCompleteList", result);
0528:                } catch (Throwable e) {
0529:                    e.printStackTrace();
0530:                }
0531:                return "autoCompleteList.jsp";
0532:            }
0533:
0534:            private String admin() {
0535:                session.put("port", "" + server.getPort());
0536:                session.put("allowOthers", "" + server.getAllowOthers());
0537:                session.put("ssl", String.valueOf(server.getSSL()));
0538:                session.put("sessions", server.getSessions());
0539:                return "admin.jsp";
0540:            }
0541:
0542:            private String adminSave() {
0543:                try {
0544:                    server.setPort(MathUtils.decodeInt((String) attributes
0545:                            .get("port")));
0546:                    server.setAllowOthers(Boolean.valueOf(
0547:                            (String) attributes.get("allowOthers"))
0548:                            .booleanValue());
0549:                    server.setSSL(Boolean.valueOf(
0550:                            (String) attributes.get("ssl")).booleanValue());
0551:                    server.saveSettings();
0552:                } catch (Exception e) {
0553:                    server.trace(e.toString());
0554:                }
0555:                return admin();
0556:            }
0557:
0558:            private String adminShutdown() {
0559:                server.shutdown();
0560:                return "admin.jsp";
0561:            }
0562:
0563:            private String index() {
0564:                String[][] languageArray = server.getLanguageArray();
0565:                String language = (String) attributes.get("language");
0566:                Locale locale = session.locale;
0567:                if (language != null) {
0568:                    if (locale == null
0569:                            || !StringUtils
0570:                                    .toLowerEnglish(locale.getLanguage())
0571:                                    .equals(language)) {
0572:                        locale = new Locale(language, "");
0573:                        server.readTranslations(session, locale.getLanguage());
0574:                        session.put("language", language);
0575:                        session.locale = locale;
0576:                    }
0577:                } else {
0578:                    language = (String) session.get("language");
0579:                }
0580:                session.put("languageCombo", getComboBox(languageArray,
0581:                        language));
0582:                String[] settingNames = server.getSettingNames();
0583:                String setting = attributes.getProperty("setting");
0584:                if (setting == null && settingNames.length > 0) {
0585:                    setting = settingNames[0];
0586:                }
0587:                String combobox = getComboBox(settingNames, setting);
0588:                session.put("settingsList", combobox);
0589:                ConnectionInfo info = server.getSetting(setting);
0590:                if (info == null) {
0591:                    info = new ConnectionInfo();
0592:                }
0593:                session.put("setting", PageParser.escapeHtml(setting));
0594:                session.put("name", PageParser.escapeHtml(setting));
0595:                session.put("driver", PageParser.escapeHtml(info.driver));
0596:                session.put("url", PageParser.escapeHtml(info.url));
0597:                session.put("user", PageParser.escapeHtml(info.user));
0598:                return "index.jsp";
0599:            }
0600:
0601:            private String getHistory() {
0602:                int id = Integer.parseInt(attributes.getProperty("id"));
0603:                String sql = session.getCommand(id);
0604:                session.put("query", PageParser.escapeHtmlData(sql));
0605:                return "query.jsp";
0606:            }
0607:
0608:            private int addColumns(DbTableOrView table, StringBuffer buff,
0609:                    int treeIndex, boolean showColumnTypes,
0610:                    StringBuffer columnsBuffer) throws SQLException {
0611:                DbColumn[] columns = table.columns;
0612:                for (int i = 0; columns != null && i < columns.length; i++) {
0613:                    DbColumn column = columns[i];
0614:                    if (columnsBuffer.length() > 0) {
0615:                        columnsBuffer.append(' ');
0616:                    }
0617:                    columnsBuffer.append(column.name);
0618:                    String col = StringUtils.urlEncode(PageParser
0619:                            .escapeJavaScript(column.name));
0620:                    buff.append("setNode(" + treeIndex + ", 1, 1, 'column', '"
0621:                            + PageParser.escapeJavaScript(column.name)
0622:                            + "', 'javascript:ins(\\'" + col + "\\')');\n");
0623:                    treeIndex++;
0624:                    if (showColumnTypes) {
0625:                        buff.append("setNode(" + treeIndex
0626:                                + ", 2, 2, 'type', '"
0627:                                + PageParser.escapeJavaScript(column.dataType)
0628:                                + "', null);\n");
0629:                        treeIndex++;
0630:                    }
0631:                }
0632:                return treeIndex;
0633:            }
0634:
0635:            private static class IndexInfo {
0636:                String name;
0637:                String type;
0638:                String columns;
0639:            }
0640:
0641:            private int addIndexes(DatabaseMetaData meta, String table,
0642:                    String schema, StringBuffer buff, int treeIndex)
0643:                    throws SQLException {
0644:                // index reading is very slow for oracle (2 seconds per index), so don't
0645:                // do it
0646:                ResultSet rs = meta.getIndexInfo(null, schema, table, false,
0647:                        false);
0648:                HashMap indexMap = new HashMap();
0649:                while (rs.next()) {
0650:                    String name = rs.getString("INDEX_NAME");
0651:                    IndexInfo info = (IndexInfo) indexMap.get(name);
0652:                    if (info == null) {
0653:                        int t = rs.getInt("TYPE");
0654:                        String type;
0655:                        if (t == DatabaseMetaData.tableIndexClustered) {
0656:                            type = "";
0657:                        } else if (t == DatabaseMetaData.tableIndexHashed) {
0658:                            type = " (${text.tree.hashed})";
0659:                        } else if (t == DatabaseMetaData.tableIndexOther) {
0660:                            type = "";
0661:                        } else {
0662:                            type = null;
0663:                        }
0664:                        if (name != null && type != null) {
0665:                            info = new IndexInfo();
0666:                            info.name = name;
0667:                            type = (rs.getBoolean("NON_UNIQUE") ? "${text.tree.nonUnique}"
0668:                                    : "${text.tree.unique}")
0669:                                    + type;
0670:                            info.type = type;
0671:                            info.columns = rs.getString("COLUMN_NAME");
0672:                            indexMap.put(name, info);
0673:                        }
0674:                    } else {
0675:                        info.columns += ", " + rs.getString("COLUMN_NAME");
0676:                    }
0677:                }
0678:                rs.close();
0679:                if (indexMap.size() > 0) {
0680:                    buff
0681:                            .append("setNode("
0682:                                    + treeIndex
0683:                                    + ", 1, 1, 'index_az', '${text.tree.indexes}', null);\n");
0684:                    treeIndex++;
0685:                    for (Iterator it = indexMap.values().iterator(); it
0686:                            .hasNext();) {
0687:                        IndexInfo info = (IndexInfo) it.next();
0688:                        buff.append("setNode(" + treeIndex
0689:                                + ", 2, 1, 'index', '"
0690:                                + PageParser.escapeJavaScript(info.name)
0691:                                + "', null);\n");
0692:                        treeIndex++;
0693:                        buff.append("setNode(" + treeIndex
0694:                                + ", 3, 2, 'type', '" + info.type
0695:                                + "', null);\n");
0696:                        treeIndex++;
0697:                        buff.append("setNode(" + treeIndex
0698:                                + ", 3, 2, 'type', '"
0699:                                + PageParser.escapeJavaScript(info.columns)
0700:                                + "', null);\n");
0701:                        treeIndex++;
0702:                    }
0703:                }
0704:                return treeIndex;
0705:            }
0706:
0707:            private int addTablesAndViews(DbSchema schema, boolean mainSchema,
0708:                    StringBuffer buff, int treeIndex) throws SQLException {
0709:                if (schema == null) {
0710:                    return treeIndex;
0711:                }
0712:                Connection conn = session.getConnection();
0713:                DatabaseMetaData meta = session.getMetaData();
0714:                int level = mainSchema ? 0 : 1;
0715:                String indentation = ", " + level + ", " + (level + 1) + ", ";
0716:                String indentNode = ", " + (level + 1) + ", " + (level + 1)
0717:                        + ", ";
0718:                DbTableOrView[] tables = schema.tables;
0719:                if (tables == null) {
0720:                    return treeIndex;
0721:                }
0722:                boolean isOracle = schema.contents.isOracle;
0723:                boolean notManyTables = tables.length < 100;
0724:                for (int i = 0; i < tables.length; i++) {
0725:                    DbTableOrView table = tables[i];
0726:                    if (table.isView) {
0727:                        continue;
0728:                    }
0729:                    int tableId = treeIndex;
0730:                    String tab = table.quotedName;
0731:                    if (!mainSchema) {
0732:                        tab = schema.quotedName + "." + tab;
0733:                    }
0734:                    tab = StringUtils.urlEncode(PageParser
0735:                            .escapeJavaScript(tab));
0736:                    buff
0737:                            .append("setNode(" + treeIndex + indentation
0738:                                    + " 'table', '"
0739:                                    + PageParser.escapeJavaScript(table.name)
0740:                                    + "', 'javascript:ins(\\'" + tab
0741:                                    + "\\',true)');\n");
0742:                    treeIndex++;
0743:                    if (mainSchema) {
0744:                        StringBuffer columnsBuffer = new StringBuffer();
0745:                        treeIndex = addColumns(table, buff, treeIndex,
0746:                                notManyTables, columnsBuffer);
0747:                        if (!isOracle && notManyTables) {
0748:                            treeIndex = addIndexes(meta, table.name,
0749:                                    schema.name, buff, treeIndex);
0750:                        }
0751:                        buff
0752:                                .append("addTable('"
0753:                                        + PageParser
0754:                                                .escapeJavaScript(table.name)
0755:                                        + "', '"
0756:                                        + PageParser
0757:                                                .escapeJavaScript(columnsBuffer
0758:                                                        .toString()) + "', "
0759:                                        + tableId + ");\n");
0760:                    }
0761:                }
0762:                tables = schema.tables;
0763:                for (int i = 0; i < tables.length; i++) {
0764:                    DbTableOrView view = tables[i];
0765:                    if (!view.isView) {
0766:                        continue;
0767:                    }
0768:                    int tableId = treeIndex;
0769:                    String tab = view.quotedName;
0770:                    if (!mainSchema) {
0771:                        tab = view.schema.quotedName + "." + tab;
0772:                    }
0773:                    tab = StringUtils.urlEncode(PageParser
0774:                            .escapeJavaScript(tab));
0775:                    buff
0776:                            .append("setNode(" + treeIndex + indentation
0777:                                    + " 'view', '"
0778:                                    + PageParser.escapeJavaScript(view.name)
0779:                                    + "', 'javascript:ins(\\'" + tab
0780:                                    + "\\',true)');\n");
0781:                    treeIndex++;
0782:                    if (mainSchema) {
0783:                        StringBuffer columnsBuffer = new StringBuffer();
0784:                        treeIndex = addColumns(view, buff, treeIndex,
0785:                                notManyTables, columnsBuffer);
0786:                        if (schema.contents.isH2) {
0787:                            PreparedStatement prep = null;
0788:                            try {
0789:                                prep = conn
0790:                                        .prepareStatement("SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=?");
0791:                                prep.setString(1, view.name);
0792:                                ResultSet rs = prep.executeQuery();
0793:                                if (rs.next()) {
0794:                                    String sql = rs.getString("SQL");
0795:                                    buff.append("setNode(" + treeIndex
0796:                                            + indentNode + " 'type', '"
0797:                                            + PageParser.escapeJavaScript(sql)
0798:                                            + "', null);\n");
0799:                                    treeIndex++;
0800:                                }
0801:                                rs.close();
0802:                            } finally {
0803:                                JdbcUtils.closeSilently(prep);
0804:                            }
0805:                        }
0806:                        buff
0807:                                .append("addTable('"
0808:                                        + PageParser
0809:                                                .escapeJavaScript(view.name)
0810:                                        + "', '"
0811:                                        + PageParser
0812:                                                .escapeJavaScript(columnsBuffer
0813:                                                        .toString()) + "', "
0814:                                        + tableId + ");\n");
0815:                    }
0816:                }
0817:                return treeIndex;
0818:            }
0819:
0820:            private String tables() {
0821:                DbContents contents = session.getContents();
0822:                boolean isH2 = false;
0823:                try {
0824:                    contents.readContents(session.getMetaData());
0825:                    session.loadBnf();
0826:                    Connection conn = session.getConnection();
0827:                    DatabaseMetaData meta = session.getMetaData();
0828:                    isH2 = contents.isH2;
0829:
0830:                    StringBuffer buff = new StringBuffer();
0831:                    buff.append("setNode(0, 0, 0, 'database', '"
0832:                            + PageParser.escapeJavaScript((String) session
0833:                                    .get("url")) + "', null);\n");
0834:                    int treeIndex = 1;
0835:
0836:                    DbSchema defaultSchema = contents.defaultSchema;
0837:                    treeIndex = addTablesAndViews(defaultSchema, true, buff,
0838:                            treeIndex);
0839:                    DbSchema[] schemas = contents.schemas;
0840:                    for (int i = 0; i < schemas.length; i++) {
0841:                        DbSchema schema = schemas[i];
0842:                        if (schema == defaultSchema || schema == null) {
0843:                            continue;
0844:                        }
0845:                        buff.append("setNode(" + treeIndex
0846:                                + ", 0, 1, 'folder', '"
0847:                                + PageParser.escapeJavaScript(schema.name)
0848:                                + "', null);\n");
0849:                        treeIndex++;
0850:                        treeIndex = addTablesAndViews(schema, false, buff,
0851:                                treeIndex);
0852:                    }
0853:                    if (isH2) {
0854:                        Statement stat = null;
0855:                        try {
0856:                            stat = conn.createStatement();
0857:                            ResultSet rs = stat
0858:                                    .executeQuery("SELECT * FROM INFORMATION_SCHEMA.SEQUENCES ORDER BY SEQUENCE_NAME");
0859:                            for (int i = 0; rs.next(); i++) {
0860:                                if (i == 0) {
0861:                                    buff
0862:                                            .append("setNode("
0863:                                                    + treeIndex
0864:                                                    + ", 0, 1, 'sequences', '${text.tree.sequences}', null);\n");
0865:                                    treeIndex++;
0866:                                }
0867:                                String name = rs.getString("SEQUENCE_NAME");
0868:                                String current = rs.getString("CURRENT_VALUE");
0869:                                String increment = rs.getString("INCREMENT");
0870:                                buff.append("setNode(" + treeIndex
0871:                                        + ", 1, 1, 'sequence', '"
0872:                                        + PageParser.escapeJavaScript(name)
0873:                                        + "', null);\n");
0874:                                treeIndex++;
0875:                                buff
0876:                                        .append("setNode("
0877:                                                + treeIndex
0878:                                                + ", 2, 2, 'type', '${text.tree.current}: "
0879:                                                + PageParser
0880:                                                        .escapeJavaScript(current)
0881:                                                + "', null);\n");
0882:                                treeIndex++;
0883:                                if (!"1".equals(increment)) {
0884:                                    buff
0885:                                            .append("setNode("
0886:                                                    + treeIndex
0887:                                                    + ", 2, 2, 'type', '${text.tree.increment}: "
0888:                                                    + PageParser
0889:                                                            .escapeJavaScript(increment)
0890:                                                    + "', null);\n");
0891:                                    treeIndex++;
0892:                                }
0893:                            }
0894:                            rs.close();
0895:                            rs = stat
0896:                                    .executeQuery("SELECT * FROM INFORMATION_SCHEMA.USERS ORDER BY NAME");
0897:                            for (int i = 0; rs.next(); i++) {
0898:                                if (i == 0) {
0899:                                    buff
0900:                                            .append("setNode("
0901:                                                    + treeIndex
0902:                                                    + ", 0, 1, 'users', '${text.tree.users}', null);\n");
0903:                                    treeIndex++;
0904:                                }
0905:                                String name = rs.getString("NAME");
0906:                                String admin = rs.getString("ADMIN");
0907:                                buff.append("setNode(" + treeIndex
0908:                                        + ", 1, 1, 'user', '"
0909:                                        + PageParser.escapeJavaScript(name)
0910:                                        + "', null);\n");
0911:                                treeIndex++;
0912:                                if (admin.equalsIgnoreCase("TRUE")) {
0913:                                    buff
0914:                                            .append("setNode("
0915:                                                    + treeIndex
0916:                                                    + ", 2, 2, 'type', '${text.tree.admin}', null);\n");
0917:                                    treeIndex++;
0918:                                }
0919:                            }
0920:                            rs.close();
0921:                        } finally {
0922:                            JdbcUtils.closeSilently(stat);
0923:                        }
0924:                    }
0925:                    String version = meta.getDatabaseProductName() + " "
0926:                            + meta.getDatabaseProductVersion();
0927:                    buff.append("setNode(" + treeIndex + ", 0, 0, 'info', '"
0928:                            + PageParser.escapeJavaScript(version)
0929:                            + "', null);\n");
0930:                    buff.append("refreshQueryTables();");
0931:                    session.put("tree", buff.toString());
0932:                } catch (Exception e) {
0933:                    session.put("tree", "");
0934:                    session.put("error", getStackTrace(0, e, isH2));
0935:                }
0936:                return "tables.jsp";
0937:            }
0938:
0939:            private String getStackTrace(int id, Throwable e, boolean isH2) {
0940:                try {
0941:                    StringWriter writer = new StringWriter();
0942:                    e.printStackTrace(new PrintWriter(writer));
0943:                    String stackTrace = writer.toString();
0944:                    stackTrace = PageParser.escapeHtml(stackTrace);
0945:                    if (isH2) {
0946:                        stackTrace = linkToSource(stackTrace);
0947:                    }
0948:                    stackTrace = StringUtils.replaceAll(stackTrace, "\t",
0949:                            "&nbsp;&nbsp;&nbsp;&nbsp;");
0950:                    String message = PageParser.escapeHtml(e.getMessage());
0951:                    String error = "<a class=\"error\" href=\"#\" onclick=\"var x=document.getElementById('st"
0952:                            + id
0953:                            + "').style;x.display=x.display==''?'none':'';\">"
0954:                            + message + "</a>";
0955:                    if (e instanceof  SQLException) {
0956:                        SQLException se = (SQLException) e;
0957:                        error += " " + se.getSQLState() + "/"
0958:                                + se.getErrorCode();
0959:                        if (isH2) {
0960:                            int code = se.getErrorCode();
0961:                            error += " <a href=\"http://h2database.com/javadoc/org/h2/constant/ErrorCode.html#c"
0962:                                    + code + "\">(${text.a.help})</a>";
0963:                        }
0964:                    }
0965:                    error += "<span style=\"display: none;\" id=\"st" + id
0966:                            + "\"><br />" + stackTrace + "</span>";
0967:                    error = formatAsError(error);
0968:                    return error;
0969:                } catch (OutOfMemoryError e2) {
0970:                    e.printStackTrace();
0971:                    return e.toString();
0972:                }
0973:            }
0974:
0975:            private String linkToSource(String s) {
0976:                try {
0977:                    StringBuffer result = new StringBuffer(s.length());
0978:                    int idx = s.indexOf("<br />");
0979:                    result.append(s.substring(0, idx));
0980:                    while (true) {
0981:                        int start = s.indexOf("org.h2.", idx);
0982:                        if (start < 0) {
0983:                            result.append(s.substring(idx));
0984:                            break;
0985:                        }
0986:                        result.append(s.substring(idx, start));
0987:                        int end = s.indexOf(')', start);
0988:                        if (end < 0) {
0989:                            result.append(s.substring(idx));
0990:                            break;
0991:                        }
0992:                        String element = s.substring(start, end);
0993:                        int open = element.lastIndexOf('(');
0994:                        int dotMethod = element.lastIndexOf('.', open - 1);
0995:                        int dotClass = element.lastIndexOf('.', dotMethod - 1);
0996:                        String packageName = element.substring(0, dotClass);
0997:                        int colon = element.lastIndexOf(':');
0998:                        String file = element.substring(open + 1, colon);
0999:                        String lineNumber = element.substring(colon + 1,
1000:                                element.length());
1001:                        String fullFileName = packageName.replace('.', '/')
1002:                                + "/" + file;
1003:                        result
1004:                                .append("<a href=\"http://h2database.com/html/source.html?file=");
1005:                        result.append(fullFileName);
1006:                        result.append("&line=");
1007:                        result.append(lineNumber);
1008:                        result.append("&build=");
1009:                        result.append(Constants.BUILD_ID);
1010:                        result.append("\">");
1011:                        result.append(element);
1012:                        result.append("</a>");
1013:                        idx = end;
1014:                    }
1015:                    return result.toString();
1016:                } catch (Throwable t) {
1017:                    return s;
1018:                }
1019:            }
1020:
1021:            private String formatAsError(String s) {
1022:                return "<div class=\"error\">" + s + "</div>";
1023:            }
1024:
1025:            private String test() {
1026:                String driver = attributes.getProperty("driver", "");
1027:                String url = attributes.getProperty("url", "");
1028:                String user = attributes.getProperty("user", "");
1029:                String password = attributes.getProperty("password", "");
1030:                session.put("driver", driver);
1031:                session.put("url", url);
1032:                session.put("user", user);
1033:                boolean isH2 = url.startsWith("jdbc:h2:");
1034:                try {
1035:                    Connection conn = server.getConnection(driver, url, user,
1036:                            password, this );
1037:                    JdbcUtils.closeSilently(conn);
1038:                    session.put("error", "${text.login.testSuccessful}");
1039:                    return "login.jsp";
1040:                } catch (Exception e) {
1041:                    session.put("error", getLoginError(e, isH2));
1042:                    return "login.jsp";
1043:                }
1044:            }
1045:
1046:            private String getLoginError(Exception e, boolean isH2) {
1047:                if (e instanceof  JdbcSQLException
1048:                        && ((JdbcSQLException) e).getErrorCode() == ErrorCode.CLASS_NOT_FOUND_1) {
1049:                    return "${text.login.driverNotFound}<br />"
1050:                            + getStackTrace(0, e, isH2);
1051:                } else {
1052:                    return getStackTrace(0, e, isH2);
1053:                }
1054:            }
1055:
1056:            private String login() {
1057:                final String driver = attributes.getProperty("driver", "");
1058:                final String url = attributes.getProperty("url", "");
1059:                final String user = attributes.getProperty("user", "");
1060:                final String password = attributes.getProperty("password", "");
1061:                session.put("autoCommit", "checked");
1062:                session.put("autoComplete", "1");
1063:                session.put("maxrows", "1000");
1064:                boolean thread = false;
1065:                if (socket != null && url.startsWith("jdbc:h2:")
1066:                        && !url.startsWith("jdbc:h2:tcp:")
1067:                        && !url.startsWith("jdbc:h2:ssl:")
1068:                        && !url.startsWith("jdbc:h2:mem:")) {
1069:                    thread = true;
1070:                }
1071:                if (!thread) {
1072:                    boolean isH2 = url.startsWith("jdbc:h2:");
1073:                    try {
1074:                        Connection conn = server.getConnection(driver, url,
1075:                                user, password, this );
1076:                        session.setConnection(conn);
1077:                        session.put("url", url);
1078:                        session.put("user", user);
1079:                        session.remove("error");
1080:                        settingSave();
1081:                        return "frame.jsp";
1082:                    } catch (Exception e) {
1083:                        session.put("error", getLoginError(e, isH2));
1084:                        return "login.jsp";
1085:                    }
1086:                }
1087:                class LoginTask implements  Runnable, DatabaseEventListener {
1088:                    private PrintWriter writer;
1089:                    private SimpleDateFormat dateFormat = new SimpleDateFormat(
1090:                            "HH:mm:ss.SSS");
1091:
1092:                    LoginTask() throws IOException {
1093:                        String message = "HTTP/1.1 200 OK\n";
1094:                        message += "Content-Type: " + mimeType + "\n\n";
1095:                        output.write(message.getBytes());
1096:                        writer = new PrintWriter(output);
1097:                        writer
1098:                                .println("<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"stylesheet.css\" /></head>");
1099:                        writer.println("<body><h2>Opening Database</h2>URL: "
1100:                                + PageParser.escapeHtml(url) + "<br />");
1101:                        writer.println("User: " + PageParser.escapeHtml(user)
1102:                                + "<br />");
1103:                        writer.println("Version: " + Constants.getVersion()
1104:                                + "<br /><br />");
1105:                        writer.flush();
1106:                        log("Start...");
1107:                    }
1108:
1109:                    public void closingDatabase() {
1110:                        log("Closing database");
1111:                    }
1112:
1113:                    public void diskSpaceIsLow(long stillAvailable)
1114:                            throws SQLException {
1115:                        log("Disk space is low; still available: "
1116:                                + stillAvailable);
1117:                    }
1118:
1119:                    public void exceptionThrown(SQLException e, String sql) {
1120:                        log("Exception: " + PageParser.escapeHtml(e.toString())
1121:                                + " SQL: " + PageParser.escapeHtml(sql));
1122:                        server.traceError(e);
1123:                    }
1124:
1125:                    public void init(String url) {
1126:                        log("Init: " + PageParser.escapeHtml(url));
1127:                    }
1128:
1129:                    public void opened() {
1130:                        log("Database was opened");
1131:                    }
1132:
1133:                    public void setProgress(int state, String name, int x,
1134:                            int max) {
1135:                        name = PageParser.escapeHtml(name);
1136:                        if (state == listenerLastState) {
1137:                            long time = System.currentTimeMillis();
1138:                            if (listenerLastEvent + 500 < time) {
1139:                                return;
1140:                            }
1141:                            listenerLastEvent = time;
1142:                        } else {
1143:                            listenerLastState = state;
1144:                        }
1145:                        switch (state) {
1146:                        case DatabaseEventListener.STATE_BACKUP_FILE:
1147:                            log("Backing up " + name + " " + (100L * x / max)
1148:                                    + "%");
1149:                            break;
1150:                        case DatabaseEventListener.STATE_CREATE_INDEX:
1151:                            log("Creating index " + name + " "
1152:                                    + (100L * x / max) + "%");
1153:                            break;
1154:                        case DatabaseEventListener.STATE_RECOVER:
1155:                            log("Recovering " + name + " " + (100L * x / max)
1156:                                    + "%");
1157:                            break;
1158:                        case DatabaseEventListener.STATE_SCAN_FILE:
1159:                            log("Scanning file " + name + " "
1160:                                    + (100L * x / max) + "%");
1161:                            break;
1162:                        default:
1163:                            log("Unknown state: " + state);
1164:                        }
1165:                    }
1166:
1167:                    private synchronized void log(String message) {
1168:                        if (output != null) {
1169:                            message = dateFormat.format(new Date()) + ": "
1170:                                    + message;
1171:                            writer.println(message + "<br />");
1172:                            writer.flush();
1173:                        }
1174:                        server.trace(message);
1175:                    }
1176:
1177:                    public void run() {
1178:                        String sessionId = (String) session.get("sessionId");
1179:                        boolean isH2 = url.startsWith("jdbc:h2:");
1180:                        try {
1181:                            Connection conn = server.getConnection(driver, url,
1182:                                    user, password, this );
1183:                            session.setConnection(conn);
1184:                            session.put("url", url);
1185:                            session.put("user", user);
1186:                            session.remove("error");
1187:                            settingSave();
1188:                            log("OK<script type=\"text/javascript\">top.location=\"frame.jsp?jsessionid="
1189:                                    + sessionId + "\"</script></body></htm>");
1190:                            // return "frame.jsp";
1191:                        } catch (Exception e) {
1192:                            session.put("error", getLoginError(e, isH2));
1193:                            log("Error<script type=\"text/javascript\">top.location=\"index.jsp?jsessionid="
1194:                                    + sessionId + "\"</script></body></html>");
1195:                            // return "index.jsp";
1196:                        }
1197:                        synchronized (this ) {
1198:                            IOUtils.closeSilently(output);
1199:                            try {
1200:                                socket.close();
1201:                            } catch (IOException e) {
1202:                                // ignore
1203:                            }
1204:                            output = null;
1205:                        }
1206:                    }
1207:                }
1208:                try {
1209:                    LoginTask login = new LoginTask();
1210:                    Thread t = new Thread(login);
1211:                    t.start();
1212:                } catch (IOException e) {
1213:                    // ignore
1214:                }
1215:                return "";
1216:            }
1217:
1218:            private String logout() {
1219:                try {
1220:                    Connection conn = session.getConnection();
1221:                    session.setConnection(null);
1222:                    session.remove("conn");
1223:                    session.remove("result");
1224:                    session.remove("tables");
1225:                    session.remove("user");
1226:                    if (conn != null) {
1227:                        conn.close();
1228:                    }
1229:                } catch (Exception e) {
1230:                    server.trace(e.toString());
1231:                }
1232:                return "index.do";
1233:            }
1234:
1235:            private String query() {
1236:                String sql = attributes.getProperty("sql").trim();
1237:                try {
1238:                    Connection conn = session.getConnection();
1239:                    String result;
1240:                    if (sql.startsWith("@JAVA")) {
1241:                        if (server.getAllowScript()) {
1242:                            try {
1243:                                result = executeJava(sql.substring("@JAVA"
1244:                                        .length()));
1245:                            } catch (Throwable t) {
1246:                                result = getStackTrace(0, t, false);
1247:                            }
1248:                        } else {
1249:                            result = "Executing Java code is not allowed, use command line parameters -webScript true";
1250:                        }
1251:                    } else if ("@AUTOCOMMIT TRUE".equals(sql)) {
1252:                        conn.setAutoCommit(true);
1253:                        result = "${text.result.autoCommitOn}";
1254:                    } else if ("@AUTOCOMMIT FALSE".equals(sql)) {
1255:                        conn.setAutoCommit(false);
1256:                        result = "${text.result.autoCommitOff}";
1257:                    } else if (sql.startsWith("@TRANSACTION_ISOLATION")) {
1258:                        String s = sql.substring(
1259:                                "@TRANSACTION_ISOLATION".length()).trim();
1260:                        if (s.length() > 0) {
1261:                            int level = Integer.parseInt(s);
1262:                            conn.setTransactionIsolation(level);
1263:                        }
1264:                        result = "Transaction Isolation: "
1265:                                + conn.getTransactionIsolation() + "<br />";
1266:                        result += Connection.TRANSACTION_READ_UNCOMMITTED
1267:                                + ": READ_UNCOMMITTED<br />";
1268:                        result += Connection.TRANSACTION_READ_COMMITTED
1269:                                + ": READ_COMMITTED<br />";
1270:                        result += Connection.TRANSACTION_REPEATABLE_READ
1271:                                + ": REPEATABLE_READ<br />";
1272:                        result += Connection.TRANSACTION_SERIALIZABLE
1273:                                + ": SERIALIZABLE";
1274:                    } else if (sql.startsWith("@SET MAXROWS ")) {
1275:                        int maxrows = Integer.parseInt(sql
1276:                                .substring("@SET MAXROWS ".length()));
1277:                        session.put("maxrows", "" + maxrows);
1278:                        result = "${text.result.maxrowsSet}";
1279:                    } else {
1280:                        ScriptReader r = new ScriptReader(new StringReader(sql));
1281:                        ObjectArray list = new ObjectArray();
1282:                        while (true) {
1283:                            String s = r.readStatement();
1284:                            if (s == null) {
1285:                                break;
1286:                            }
1287:                            list.add(s);
1288:                        }
1289:                        StringBuffer buff = new StringBuffer();
1290:                        for (int i = 0; i < list.size(); i++) {
1291:                            String s = (String) list.get(i);
1292:                            if (!s.startsWith("@")) {
1293:                                buff.append(PageParser.escapeHtml(s + ";"));
1294:                                buff.append("<br />");
1295:                            }
1296:                            buff.append(getResult(conn, i + 1, s,
1297:                                    list.size() == 1, false));
1298:                            buff.append("<br />");
1299:                        }
1300:                        result = buff.toString();
1301:                    }
1302:                    session.put("result", result);
1303:                } catch (Throwable e) {
1304:                    session.put("result", getStackTrace(0, e, session
1305:                            .getContents().isH2));
1306:                }
1307:                return "result.jsp";
1308:            }
1309:
1310:            static class DynamicClassLoader extends SecureClassLoader {
1311:
1312:                private String name;
1313:                private byte[] data;
1314:                private Class clazz;
1315:
1316:                DynamicClassLoader(String name, byte[] data)
1317:                        throws MalformedURLException {
1318:                    super (DynamicClassLoader.class.getClassLoader());
1319:                    this .name = name;
1320:                    this .data = data;
1321:                }
1322:
1323:                public Class loadClass(String className)
1324:                        throws ClassNotFoundException {
1325:                    return findClass(className);
1326:                }
1327:
1328:                public Class findClass(String className)
1329:                        throws ClassNotFoundException {
1330:                    if (className.equals(name)) {
1331:                        if (clazz == null) {
1332:                            clazz = defineClass(className, data, 0, data.length);
1333:                        }
1334:                        return clazz;
1335:                    }
1336:                    try {
1337:                        return findSystemClass(className);
1338:                    } catch (Exception e) {
1339:                    }
1340:                    return super .findClass(className);
1341:                }
1342:            }
1343:
1344:            private String executeJava(String code) throws Exception {
1345:                File javaFile = new File("Java.java");
1346:                File classFile = new File("Java.class");
1347:                try {
1348:                    PrintWriter out = new PrintWriter(new FileWriter(javaFile));
1349:                    classFile.delete();
1350:                    int endImport = code.indexOf("@CODE");
1351:                    String importCode = "import java.util.*; import java.math.*; import java.sql.*;";
1352:                    if (endImport >= 0) {
1353:                        importCode = code.substring(0, endImport);
1354:                        code = code.substring("@CODE".length() + endImport);
1355:                    }
1356:                    out.println(importCode);
1357:                    out
1358:                            .println("public class Java { public static Object run() throws Throwable {"
1359:                                    + code + "}}");
1360:                    out.close();
1361:                    Process p = Runtime.getRuntime().exec("javac Java.java");
1362:                    InputStream processIn = p.getInputStream();
1363:                    InputStream processErrorIn = p.getErrorStream();
1364:                    StringBuffer buff = new StringBuffer();
1365:                    while (true) {
1366:                        int c = processIn.read();
1367:                        if (c == -1) {
1368:                            break;
1369:                        }
1370:                        buff.append((char) c);
1371:                    }
1372:                    while (true) {
1373:                        int c = processErrorIn.read();
1374:                        if (c == -1) {
1375:                            break;
1376:                        }
1377:                        buff.append((char) c);
1378:                    }
1379:                    String error = buff.toString().trim();
1380:                    if (error.length() > 0) {
1381:                        throw new Exception("Error compiling: " + error);
1382:                    }
1383:                    byte[] data = new byte[(int) classFile.length()];
1384:                    DataInputStream in = new DataInputStream(
1385:                            new FileInputStream(classFile));
1386:                    in.readFully(data);
1387:                    in.close();
1388:                    DynamicClassLoader cl = new DynamicClassLoader("Java", data);
1389:                    Class clazz = cl.loadClass("Java");
1390:                    Method[] methods = clazz.getMethods();
1391:                    for (int i = 0; i < methods.length; i++) {
1392:                        Method m = methods[i];
1393:                        if (m.getName().equals("run")) {
1394:                            return "" + m.invoke(null, new Object[0]);
1395:                        }
1396:                    }
1397:                    return null;
1398:                } finally {
1399:                    javaFile.delete();
1400:                    classFile.delete();
1401:                }
1402:            }
1403:
1404:            private String editResult() {
1405:                ResultSet rs = session.result;
1406:                int row = Integer.parseInt(attributes.getProperty("row"));
1407:                int op = Integer.parseInt(attributes.getProperty("op"));
1408:                String result = "", error = "";
1409:                try {
1410:                    if (op == 1) {
1411:                        boolean insert = row < 0;
1412:                        if (insert) {
1413:                            rs.moveToInsertRow();
1414:                        } else {
1415:                            rs.absolute(row);
1416:                        }
1417:                        for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
1418:                            String x = attributes.getProperty("r" + row + "c"
1419:                                    + (i + 1));
1420:                            rs.updateString(i + 1, unescapeData(x));
1421:                        }
1422:                        if (insert) {
1423:                            rs.insertRow();
1424:                        } else {
1425:                            rs.updateRow();
1426:                        }
1427:                    } else if (op == 2) {
1428:                        rs.absolute(row);
1429:                        rs.deleteRow();
1430:                    } else if (op == 3) {
1431:                        // cancel
1432:                    }
1433:                } catch (Throwable e) {
1434:                    result = "<br />"
1435:                            + getStackTrace(0, e, session.getContents().isH2);
1436:                    error = formatAsError(e.getMessage());
1437:                }
1438:                String sql = "@EDIT " + (String) session.get("resultSetSQL");
1439:                Connection conn = session.getConnection();
1440:                result = error + getResult(conn, -1, sql, true, true) + result;
1441:                session.put("result", result);
1442:                return "result.jsp";
1443:            }
1444:
1445:            private ResultSet getMetaResultSet(Connection conn, String sql)
1446:                    throws SQLException {
1447:                DatabaseMetaData meta = conn.getMetaData();
1448:                if (sql.startsWith("@TABLES")) {
1449:                    String[] p = split(sql);
1450:                    String[] types = p[4] == null ? null : StringUtils
1451:                            .arraySplit(p[4], ',', false);
1452:                    return meta.getTables(p[1], p[2], p[3], types);
1453:                } else if (sql.startsWith("@COLUMNS")) {
1454:                    String[] p = split(sql);
1455:                    return meta.getColumns(p[1], p[2], p[3], p[4]);
1456:                } else if (sql.startsWith("@INDEX_INFO")) {
1457:                    String[] p = split(sql);
1458:                    boolean unique = p[4] == null ? false : Boolean.valueOf(
1459:                            p[4]).booleanValue();
1460:                    boolean approx = p[5] == null ? false : Boolean.valueOf(
1461:                            p[5]).booleanValue();
1462:                    return meta.getIndexInfo(p[1], p[2], p[3], unique, approx);
1463:                } else if (sql.startsWith("@PRIMARY_KEYS")) {
1464:                    String[] p = split(sql);
1465:                    return meta.getPrimaryKeys(p[1], p[2], p[3]);
1466:                } else if (sql.startsWith("@PROCEDURES")) {
1467:                    String[] p = split(sql);
1468:                    return meta.getProcedures(p[1], p[2], p[3]);
1469:                } else if (sql.startsWith("@PROCEDURE_COLUMNS")) {
1470:                    String[] p = split(sql);
1471:                    return meta.getProcedureColumns(p[1], p[2], p[3], p[4]);
1472:                } else if (sql.startsWith("@SCHEMAS")) {
1473:                    return meta.getSchemas();
1474:                } else if (sql.startsWith("@CATALOG")) {
1475:                    SimpleResultSet rs = new SimpleResultSet();
1476:                    rs.addColumn("CATALOG", Types.VARCHAR, 0, 0);
1477:                    rs.addRow(new String[] { conn.getCatalog() });
1478:                    return rs;
1479:                } else if (sql.startsWith("@MEMORY")) {
1480:                    SimpleResultSet rs = new SimpleResultSet();
1481:                    rs.addColumn("Type", Types.VARCHAR, 0, 0);
1482:                    rs.addColumn("Value", Types.VARCHAR, 0, 0);
1483:                    rs.addRow(new String[] { "Used Memory",
1484:                            "" + MemoryUtils.getMemoryUsed() });
1485:                    rs.addRow(new String[] { "Free Memory",
1486:                            "" + MemoryUtils.getMemoryFree() });
1487:                    return rs;
1488:                } else if (sql.startsWith("@INFO")) {
1489:                    SimpleResultSet rs = new SimpleResultSet();
1490:                    rs.addColumn("KEY", Types.VARCHAR, 0, 0);
1491:                    rs.addColumn("VALUE", Types.VARCHAR, 0, 0);
1492:                    rs.addRow(new String[] { "conn.getCatalog",
1493:                            conn.getCatalog() });
1494:                    rs.addRow(new String[] { "conn.getAutoCommit",
1495:                            "" + conn.getAutoCommit() });
1496:                    rs.addRow(new String[] { "conn.getTransactionIsolation",
1497:                            "" + conn.getTransactionIsolation() });
1498:                    rs.addRow(new String[] { "conn.getWarnings",
1499:                            "" + conn.getWarnings() });
1500:                    String map;
1501:                    try {
1502:                        map = "" + conn.getTypeMap();
1503:                    } catch (SQLException e) {
1504:                        map = e.toString();
1505:                    }
1506:                    rs.addRow(new String[] { "conn.getTypeMap", "" + map });
1507:                    rs.addRow(new String[] { "conn.isReadOnly",
1508:                            "" + conn.isReadOnly() });
1509:                    rs.addRow(new String[] { "meta.getCatalogSeparator",
1510:                            "" + meta.getCatalogSeparator() });
1511:                    rs.addRow(new String[] { "meta.getCatalogTerm",
1512:                            "" + meta.getCatalogTerm() });
1513:                    rs.addRow(new String[] { "meta.getDatabaseProductName",
1514:                            "" + meta.getDatabaseProductName() });
1515:                    rs.addRow(new String[] { "meta.getDatabaseProductVersion",
1516:                            "" + meta.getDatabaseProductVersion() });
1517:                    rs.addRow(new String[] {
1518:                            "meta.getDefaultTransactionIsolation",
1519:                            "" + meta.getDefaultTransactionIsolation() });
1520:                    rs.addRow(new String[] { "meta.getDriverMajorVersion",
1521:                            "" + meta.getDriverMajorVersion() });
1522:                    rs.addRow(new String[] { "meta.getDriverMinorVersion",
1523:                            "" + meta.getDriverMinorVersion() });
1524:                    rs.addRow(new String[] { "meta.getDriverName",
1525:                            "" + meta.getDriverName() });
1526:                    rs.addRow(new String[] { "meta.getDriverVersion",
1527:                            "" + meta.getDriverVersion() });
1528:                    rs.addRow(new String[] { "meta.getExtraNameCharacters",
1529:                            "" + meta.getExtraNameCharacters() });
1530:                    rs.addRow(new String[] { "meta.getIdentifierQuoteString",
1531:                            "" + meta.getIdentifierQuoteString() });
1532:                    rs.addRow(new String[] { "meta.getMaxBinaryLiteralLength",
1533:                            "" + meta.getMaxBinaryLiteralLength() });
1534:                    rs.addRow(new String[] { "meta.getMaxCatalogNameLength",
1535:                            "" + meta.getMaxCatalogNameLength() });
1536:                    rs.addRow(new String[] { "meta.getMaxCharLiteralLength",
1537:                            "" + meta.getMaxCharLiteralLength() });
1538:                    rs.addRow(new String[] { "meta.getMaxColumnNameLength",
1539:                            "" + meta.getMaxColumnNameLength() });
1540:                    rs.addRow(new String[] { "meta.getMaxColumnsInGroupBy",
1541:                            "" + meta.getMaxColumnsInGroupBy() });
1542:                    rs.addRow(new String[] { "meta.getMaxColumnsInIndex",
1543:                            "" + meta.getMaxColumnsInIndex() });
1544:                    rs.addRow(new String[] { "meta.getMaxColumnsInOrderBy",
1545:                            "" + meta.getMaxColumnsInOrderBy() });
1546:                    rs.addRow(new String[] { "meta.getMaxColumnsInSelect",
1547:                            "" + meta.getMaxColumnsInSelect() });
1548:                    rs.addRow(new String[] { "meta.getMaxColumnsInTable",
1549:                            "" + meta.getMaxColumnsInTable() });
1550:                    rs.addRow(new String[] { "meta.getMaxConnections",
1551:                            "" + meta.getMaxConnections() });
1552:                    rs.addRow(new String[] { "meta.getMaxCursorNameLength",
1553:                            "" + meta.getMaxCursorNameLength() });
1554:                    rs.addRow(new String[] { "meta.getMaxIndexLength",
1555:                            "" + meta.getMaxIndexLength() });
1556:                    rs.addRow(new String[] { "meta.getMaxProcedureNameLength",
1557:                            "" + meta.getMaxProcedureNameLength() });
1558:                    rs.addRow(new String[] { "meta.getMaxRowSize",
1559:                            "" + meta.getMaxRowSize() });
1560:                    rs.addRow(new String[] { "meta.getMaxSchemaNameLength",
1561:                            "" + meta.getMaxSchemaNameLength() });
1562:                    rs.addRow(new String[] { "meta.getMaxStatementLength",
1563:                            "" + meta.getMaxStatementLength() });
1564:                    rs.addRow(new String[] { "meta.getMaxStatements",
1565:                            "" + meta.getMaxStatements() });
1566:                    rs.addRow(new String[] { "meta.getMaxTableNameLength",
1567:                            "" + meta.getMaxTableNameLength() });
1568:                    rs.addRow(new String[] { "meta.getMaxTablesInSelect",
1569:                            "" + meta.getMaxTablesInSelect() });
1570:                    rs.addRow(new String[] { "meta.getMaxUserNameLength",
1571:                            "" + meta.getMaxUserNameLength() });
1572:                    rs.addRow(new String[] { "meta.getNumericFunctions",
1573:                            "" + meta.getNumericFunctions() });
1574:                    rs.addRow(new String[] { "meta.getProcedureTerm",
1575:                            "" + meta.getProcedureTerm() });
1576:                    rs.addRow(new String[] { "meta.getSchemaTerm",
1577:                            "" + meta.getSchemaTerm() });
1578:                    rs.addRow(new String[] { "meta.getSearchStringEscape",
1579:                            "" + meta.getSearchStringEscape() });
1580:                    rs.addRow(new String[] { "meta.getSQLKeywords",
1581:                            "" + meta.getSQLKeywords() });
1582:                    rs.addRow(new String[] { "meta.getStringFunctions",
1583:                            "" + meta.getStringFunctions() });
1584:                    rs.addRow(new String[] { "meta.getSystemFunctions",
1585:                            "" + meta.getSystemFunctions() });
1586:                    rs.addRow(new String[] { "meta.getTimeDateFunctions",
1587:                            "" + meta.getTimeDateFunctions() });
1588:                    rs
1589:                            .addRow(new String[] { "meta.getURL",
1590:                                    "" + meta.getURL() });
1591:                    rs.addRow(new String[] { "meta.getUserName",
1592:                            "" + meta.getUserName() });
1593:                    rs.addRow(new String[] { "meta.isCatalogAtStart",
1594:                            "" + meta.isCatalogAtStart() });
1595:                    rs.addRow(new String[] { "meta.isReadOnly",
1596:                            "" + meta.isReadOnly() });
1597:                    rs.addRow(new String[] { "meta.allProceduresAreCallable",
1598:                            "" + meta.allProceduresAreCallable() });
1599:                    rs.addRow(new String[] { "meta.allTablesAreSelectable",
1600:                            "" + meta.allTablesAreSelectable() });
1601:                    rs
1602:                            .addRow(new String[] {
1603:                                    "meta.dataDefinitionCausesTransactionCommit",
1604:                                    ""
1605:                                            + meta
1606:                                                    .dataDefinitionCausesTransactionCommit() });
1607:                    rs.addRow(new String[] {
1608:                            "meta.dataDefinitionIgnoredInTransactions",
1609:                            "" + meta.dataDefinitionIgnoredInTransactions() });
1610:                    rs.addRow(new String[] { "meta.doesMaxRowSizeIncludeBlobs",
1611:                            "" + meta.doesMaxRowSizeIncludeBlobs() });
1612:                    rs.addRow(new String[] { "meta.nullPlusNonNullIsNull",
1613:                            "" + meta.nullPlusNonNullIsNull() });
1614:                    rs.addRow(new String[] { "meta.nullsAreSortedAtEnd",
1615:                            "" + meta.nullsAreSortedAtEnd() });
1616:                    rs.addRow(new String[] { "meta.nullsAreSortedAtStart",
1617:                            "" + meta.nullsAreSortedAtStart() });
1618:                    rs.addRow(new String[] { "meta.nullsAreSortedHigh",
1619:                            "" + meta.nullsAreSortedHigh() });
1620:                    rs.addRow(new String[] { "meta.nullsAreSortedLow",
1621:                            "" + meta.nullsAreSortedLow() });
1622:                    rs.addRow(new String[] { "meta.storesLowerCaseIdentifiers",
1623:                            "" + meta.storesLowerCaseIdentifiers() });
1624:                    rs.addRow(new String[] {
1625:                            "meta.storesLowerCaseQuotedIdentifiers",
1626:                            "" + meta.storesLowerCaseQuotedIdentifiers() });
1627:                    rs.addRow(new String[] { "meta.storesMixedCaseIdentifiers",
1628:                            "" + meta.storesMixedCaseIdentifiers() });
1629:                    rs.addRow(new String[] {
1630:                            "meta.storesMixedCaseQuotedIdentifiers",
1631:                            "" + meta.storesMixedCaseQuotedIdentifiers() });
1632:                    rs.addRow(new String[] { "meta.storesUpperCaseIdentifiers",
1633:                            "" + meta.storesUpperCaseIdentifiers() });
1634:                    rs.addRow(new String[] {
1635:                            "meta.storesUpperCaseQuotedIdentifiers",
1636:                            "" + meta.storesUpperCaseQuotedIdentifiers() });
1637:                    rs.addRow(new String[] {
1638:                            "meta.supportsAlterTableWithAddColumn",
1639:                            "" + meta.supportsAlterTableWithAddColumn() });
1640:                    rs.addRow(new String[] {
1641:                            "meta.supportsAlterTableWithDropColumn",
1642:                            "" + meta.supportsAlterTableWithDropColumn() });
1643:                    rs.addRow(new String[] {
1644:                            "meta.supportsANSI92EntryLevelSQL",
1645:                            "" + meta.supportsANSI92EntryLevelSQL() });
1646:                    rs.addRow(new String[] { "meta.supportsANSI92FullSQL",
1647:                            "" + meta.supportsANSI92FullSQL() });
1648:                    rs.addRow(new String[] {
1649:                            "meta.supportsANSI92IntermediateSQL",
1650:                            "" + meta.supportsANSI92IntermediateSQL() });
1651:                    rs.addRow(new String[] { "meta.supportsBatchUpdates",
1652:                            "" + meta.supportsBatchUpdates() });
1653:                    rs.addRow(new String[] {
1654:                            "meta.supportsCatalogsInDataManipulation",
1655:                            "" + meta.supportsCatalogsInDataManipulation() });
1656:                    rs.addRow(new String[] {
1657:                            "meta.supportsCatalogsInIndexDefinitions",
1658:                            "" + meta.supportsCatalogsInIndexDefinitions() });
1659:                    rs
1660:                            .addRow(new String[] {
1661:                                    "meta.supportsCatalogsInPrivilegeDefinitions",
1662:                                    ""
1663:                                            + meta
1664:                                                    .supportsCatalogsInPrivilegeDefinitions() });
1665:                    rs.addRow(new String[] {
1666:                            "meta.supportsCatalogsInProcedureCalls",
1667:                            "" + meta.supportsCatalogsInProcedureCalls() });
1668:                    rs.addRow(new String[] {
1669:                            "meta.supportsCatalogsInTableDefinitions",
1670:                            "" + meta.supportsCatalogsInTableDefinitions() });
1671:                    rs.addRow(new String[] { "meta.supportsColumnAliasing",
1672:                            "" + meta.supportsColumnAliasing() });
1673:                    rs.addRow(new String[] { "meta.supportsConvert",
1674:                            "" + meta.supportsConvert() });
1675:                    rs.addRow(new String[] { "meta.supportsCoreSQLGrammar",
1676:                            "" + meta.supportsCoreSQLGrammar() });
1677:                    rs.addRow(new String[] {
1678:                            "meta.supportsCorrelatedSubqueries",
1679:                            "" + meta.supportsCorrelatedSubqueries() });
1680:                    rs
1681:                            .addRow(new String[] {
1682:                                    "meta.supportsDataDefinitionAndDataManipulationTransactions",
1683:                                    ""
1684:                                            + meta
1685:                                                    .supportsDataDefinitionAndDataManipulationTransactions() });
1686:                    rs
1687:                            .addRow(new String[] {
1688:                                    "meta.supportsDataManipulationTransactionsOnly",
1689:                                    ""
1690:                                            + meta
1691:                                                    .supportsDataManipulationTransactionsOnly() });
1692:                    rs
1693:                            .addRow(new String[] {
1694:                                    "meta.supportsDifferentTableCorrelationNames",
1695:                                    ""
1696:                                            + meta
1697:                                                    .supportsDifferentTableCorrelationNames() });
1698:                    rs.addRow(new String[] {
1699:                            "meta.supportsExpressionsInOrderBy",
1700:                            "" + meta.supportsExpressionsInOrderBy() });
1701:                    rs.addRow(new String[] { "meta.supportsExtendedSQLGrammar",
1702:                            "" + meta.supportsExtendedSQLGrammar() });
1703:                    rs.addRow(new String[] { "meta.supportsFullOuterJoins",
1704:                            "" + meta.supportsFullOuterJoins() });
1705:                    rs.addRow(new String[] { "meta.supportsGroupBy",
1706:                            "" + meta.supportsGroupBy() });
1707:                    // TODO meta data: more supports methods (I'm tired now)
1708:                    rs.addRow(new String[] { "meta.usesLocalFilePerTable",
1709:                            "" + meta.usesLocalFilePerTable() });
1710:                    rs.addRow(new String[] { "meta.usesLocalFiles",
1711:                            "" + meta.usesLocalFiles() });
1712:                    //#ifdef JDK14
1713:                    rs.addRow(new String[] { "conn.getHoldability",
1714:                            "" + conn.getHoldability() });
1715:                    rs.addRow(new String[] { "meta.getDatabaseMajorVersion",
1716:                            "" + meta.getDatabaseMajorVersion() });
1717:                    rs.addRow(new String[] { "meta.getDatabaseMinorVersion",
1718:                            "" + meta.getDatabaseMinorVersion() });
1719:                    rs.addRow(new String[] { "meta.getJDBCMajorVersion",
1720:                            "" + meta.getJDBCMajorVersion() });
1721:                    rs.addRow(new String[] { "meta.getJDBCMinorVersion",
1722:                            "" + meta.getJDBCMinorVersion() });
1723:                    rs.addRow(new String[] { "meta.getResultSetHoldability",
1724:                            "" + meta.getResultSetHoldability() });
1725:                    rs.addRow(new String[] { "meta.getSQLStateType",
1726:                            "" + meta.getSQLStateType() });
1727:                    rs.addRow(new String[] { "meta.supportsGetGeneratedKeys",
1728:                            "" + meta.supportsGetGeneratedKeys() });
1729:                    rs.addRow(new String[] { "meta.locatorsUpdateCopy",
1730:                            "" + meta.locatorsUpdateCopy() });
1731:                    //#endif
1732:                    return rs;
1733:                } else if (sql.startsWith("@CATALOGS")) {
1734:                    return meta.getCatalogs();
1735:                } else if (sql.startsWith("@TABLE_TYPES")) {
1736:                    return meta.getTableTypes();
1737:                } else if (sql.startsWith("@COLUMN_PRIVILEGES")) {
1738:                    String[] p = split(sql);
1739:                    return meta.getColumnPrivileges(p[1], p[2], p[3], p[4]);
1740:                } else if (sql.startsWith("@TABLE_PRIVILEGES")) {
1741:                    String[] p = split(sql);
1742:                    return meta.getTablePrivileges(p[1], p[2], p[3]);
1743:                } else if (sql.startsWith("@BEST_ROW_IDENTIFIER")) {
1744:                    String[] p = split(sql);
1745:                    int scale = p[4] == null ? 0 : Integer.parseInt(p[4]);
1746:                    boolean nullable = p[5] == null ? false : Boolean.valueOf(
1747:                            p[5]).booleanValue();
1748:                    return meta.getBestRowIdentifier(p[1], p[2], p[3], scale,
1749:                            nullable);
1750:                } else if (sql.startsWith("@VERSION_COLUMNS")) {
1751:                    String[] p = split(sql);
1752:                    return meta.getVersionColumns(p[1], p[2], p[3]);
1753:                } else if (sql.startsWith("@IMPORTED_KEYS")) {
1754:                    String[] p = split(sql);
1755:                    return meta.getImportedKeys(p[1], p[2], p[3]);
1756:                } else if (sql.startsWith("@EXPORTED_KEYS")) {
1757:                    String[] p = split(sql);
1758:                    return meta.getExportedKeys(p[1], p[2], p[3]);
1759:                } else if (sql.startsWith("@CROSS_REFERENCE")) {
1760:                    String[] p = split(sql);
1761:                    return meta.getCrossReference(p[1], p[2], p[3], p[4], p[5],
1762:                            p[6]);
1763:                } else if (sql.startsWith("@UDTS")) {
1764:                    String[] p = split(sql);
1765:                    int[] types;
1766:                    if (p[4] == null) {
1767:                        types = null;
1768:                    } else {
1769:                        String[] t = StringUtils.arraySplit(p[4], ',', false);
1770:                        types = new int[t.length];
1771:                        for (int i = 0; i < t.length; i++) {
1772:                            types[i] = Integer.parseInt(t[i]);
1773:                        }
1774:                    }
1775:                    return meta.getUDTs(p[1], p[2], p[3], types);
1776:                } else if (sql.startsWith("@TYPE_INFO")) {
1777:                    return meta.getTypeInfo();
1778:                    //#ifdef JDK14
1779:                } else if (sql.startsWith("@SUPER_TYPES")) {
1780:                    String[] p = split(sql);
1781:                    return meta.getSuperTypes(p[1], p[2], p[3]);
1782:                } else if (sql.startsWith("@SUPER_TABLES")) {
1783:                    String[] p = split(sql);
1784:                    return meta.getSuperTables(p[1], p[2], p[3]);
1785:                } else if (sql.startsWith("@ATTRIBUTES")) {
1786:                    String[] p = split(sql);
1787:                    return meta.getAttributes(p[1], p[2], p[3], p[4]);
1788:                    //#endif
1789:                }
1790:                return null;
1791:            }
1792:
1793:            private String[] split(String s) {
1794:                String[] list = new String[10];
1795:                String[] t = StringUtils.arraySplit(s, ' ', true);
1796:                System.arraycopy(t, 0, list, 0, t.length);
1797:                for (int i = 0; i < list.length; i++) {
1798:                    if ("null".equals(list[i])) {
1799:                        list[i] = null;
1800:                    }
1801:                }
1802:                return list;
1803:            }
1804:
1805:            private int getMaxrows() {
1806:                String r = (String) session.get("maxrows");
1807:                int maxrows = r == null ? 0 : Integer.parseInt(r);
1808:                return maxrows;
1809:            }
1810:
1811:            private String getResult(Connection conn, int id, String sql,
1812:                    boolean allowEdit, boolean forceEdit) {
1813:                try {
1814:                    sql = sql.trim();
1815:                    StringBuffer buff = new StringBuffer();
1816:                    String sqlUpper = StringUtils.toUpperEnglish(sql);
1817:                    if (sqlUpper.indexOf("CREATE") >= 0
1818:                            || sqlUpper.indexOf("DROP") >= 0
1819:                            || sqlUpper.indexOf("ALTER") >= 0
1820:                            || sqlUpper.indexOf("RUNSCRIPT") >= 0) {
1821:                        String sessionId = attributes.getProperty("jsessionid");
1822:                        buff
1823:                                .append("<script type=\"text/javascript\">top['h2menu'].location='tables.do?jsessionid="
1824:                                        + sessionId + "';</script>");
1825:                    }
1826:                    Statement stat;
1827:                    DbContents contents = session.getContents();
1828:                    if (forceEdit || (allowEdit && contents.isH2)) {
1829:                        stat = conn.createStatement(
1830:                                ResultSet.TYPE_SCROLL_INSENSITIVE,
1831:                                ResultSet.CONCUR_UPDATABLE);
1832:                    } else {
1833:                        stat = conn.createStatement();
1834:                    }
1835:                    ResultSet rs;
1836:                    long time = System.currentTimeMillis();
1837:                    boolean metadata = false;
1838:                    boolean generatedKeys = false;
1839:                    boolean edit = false;
1840:                    boolean list = false;
1841:                    if ("@CANCEL".equals(sql)) {
1842:                        stat = session.executingStatement;
1843:                        if (stat != null) {
1844:                            stat.cancel();
1845:                            buff.append("${text.result.statementWasCancelled}");
1846:                        } else {
1847:                            buff.append("${text.result.noRunningStatement}");
1848:                        }
1849:                        return buff.toString();
1850:                    } else if (sql.startsWith("@PARAMETER_META")) {
1851:                        sql = sql.substring("@PARAMETER_META".length()).trim();
1852:                        PreparedStatement prep = conn.prepareStatement(sql);
1853:                        buff.append(getParameterResultSet(prep
1854:                                .getParameterMetaData()));
1855:                        return buff.toString();
1856:                    } else if (sql.startsWith("@META")) {
1857:                        metadata = true;
1858:                        sql = sql.substring("@META".length()).trim();
1859:                    } else if (sql.startsWith("@LIST")) {
1860:                        list = true;
1861:                        sql = sql.substring("@LIST".length()).trim();
1862:                    } else if (sql.startsWith("@GENERATED")) {
1863:                        generatedKeys = true;
1864:                        sql = sql.substring("@GENERATED".length()).trim();
1865:                    } else if (sql.startsWith("@LOOP")) {
1866:                        metadata = true;
1867:                        sql = sql.substring("@LOOP".length()).trim();
1868:                        int idx = sql.indexOf(' ');
1869:                        int count = MathUtils.decodeInt(sql.substring(0, idx));
1870:                        sql = sql.substring(idx).trim();
1871:                        return executeLoop(conn, count, sql);
1872:                    } else if (sql.startsWith("@EDIT")) {
1873:                        edit = true;
1874:                        sql = sql.substring("@EDIT".length()).trim();
1875:                        session.put("resultSetSQL", sql);
1876:                    } else if ("@HISTORY".equals(sql)) {
1877:                        buff.append(getHistoryString());
1878:                        return buff.toString();
1879:                    }
1880:                    if (sql.startsWith("@")) {
1881:                        rs = getMetaResultSet(conn, sql);
1882:                        if (rs == null) {
1883:                            buff.append("?: " + sql);
1884:                            return buff.toString();
1885:                        }
1886:                    } else {
1887:                        int maxrows = getMaxrows();
1888:                        stat.setMaxRows(maxrows);
1889:                        session.executingStatement = stat;
1890:                        boolean isResultSet = stat.execute(sql);
1891:                        session.addCommand(sql);
1892:                        if (generatedKeys) {
1893:                            rs = null;
1894:                            //#ifdef JDK14
1895:                            rs = stat.getGeneratedKeys();
1896:                            //#endif
1897:                        } else {
1898:                            if (!isResultSet) {
1899:                                buff.append("${text.result.updateCount}: "
1900:                                        + stat.getUpdateCount());
1901:                                time = System.currentTimeMillis() - time;
1902:                                buff.append("<br />(");
1903:                                buff.append(time);
1904:                                buff.append(" ms)");
1905:                                stat.close();
1906:                                return buff.toString();
1907:                            }
1908:                            rs = stat.getResultSet();
1909:                        }
1910:                    }
1911:                    time = System.currentTimeMillis() - time;
1912:                    buff.append(getResultSet(sql, rs, metadata, list, edit,
1913:                            time, allowEdit));
1914:                    // SQLWarning warning = stat.getWarnings();
1915:                    // if(warning != null) {
1916:                    // buff.append("<br />Warning:<br />");
1917:                    // buff.append(getStackTrace(id, warning));
1918:                    // }
1919:                    if (!edit) {
1920:                        stat.close();
1921:                    }
1922:                    return buff.toString();
1923:                } catch (Throwable e) {
1924:                    // throwable: including OutOfMemoryError and so on
1925:                    return getStackTrace(id, e, session.getContents().isH2);
1926:                } finally {
1927:                    session.executingStatement = null;
1928:                }
1929:            }
1930:
1931:            private String executeLoop(Connection conn, int count, String sql)
1932:                    throws SQLException {
1933:                ArrayList params = new ArrayList();
1934:                int idx = 0;
1935:                while (!stop) {
1936:                    idx = sql.indexOf('?', idx);
1937:                    if (idx < 0) {
1938:                        break;
1939:                    }
1940:                    if (sql.substring(idx).startsWith("?/*RND*/")) {
1941:                        params.add(ObjectUtils.getInteger(1));
1942:                        sql = sql.substring(0, idx) + "?"
1943:                                + sql.substring(idx + "/*RND*/".length() + 1);
1944:                    } else {
1945:                        params.add(ObjectUtils.getInteger(0));
1946:                    }
1947:                    idx++;
1948:                }
1949:                int rows = 0;
1950:                boolean prepared;
1951:                Random random = new Random(1);
1952:                long time = System.currentTimeMillis();
1953:                if (sql.startsWith("@STATEMENT")) {
1954:                    sql = sql.substring("@STATEMENT".length()).trim();
1955:                    prepared = false;
1956:                    Statement stat = conn.createStatement();
1957:                    for (int i = 0; !stop && i < count; i++) {
1958:                        String s = sql;
1959:                        for (int j = 0; j < params.size(); j++) {
1960:                            idx = s.indexOf('?');
1961:                            Integer type = (Integer) params.get(j);
1962:                            if (type.intValue() == 1) {
1963:                                s = s.substring(0, idx) + random.nextInt(count)
1964:                                        + s.substring(idx + 1);
1965:                            } else {
1966:                                s = s.substring(0, idx) + i
1967:                                        + s.substring(idx + 1);
1968:                            }
1969:                        }
1970:                        if (stat.execute(s)) {
1971:                            ResultSet rs = stat.getResultSet();
1972:                            while (!stop && rs.next()) {
1973:                                rows++;
1974:                                // maybe get the data as well
1975:                            }
1976:                            rs.close();
1977:                            // maybe close result set
1978:                        }
1979:                    }
1980:                } else {
1981:                    prepared = true;
1982:                    PreparedStatement prep = conn.prepareStatement(sql);
1983:                    for (int i = 0; !stop && i < count; i++) {
1984:                        for (int j = 0; j < params.size(); j++) {
1985:                            Integer type = (Integer) params.get(j);
1986:                            if (type.intValue() == 1) {
1987:                                prep.setInt(j + 1, random.nextInt(count));
1988:                            } else {
1989:                                prep.setInt(j + 1, i);
1990:                            }
1991:                        }
1992:                        if (session.getContents().isSQLite) {
1993:                            // SQLite currently throws an exception on prep.execute()
1994:                            prep.executeUpdate();
1995:                        } else {
1996:                            if (prep.execute()) {
1997:                                ResultSet rs = prep.getResultSet();
1998:                                while (!stop && rs.next()) {
1999:                                    rows++;
2000:                                    // maybe get the data as well
2001:                                }
2002:                                rs.close();
2003:                            }
2004:                        }
2005:                    }
2006:                }
2007:                time = System.currentTimeMillis() - time;
2008:                String result = time + " ms: " + count + " * ";
2009:                if (prepared) {
2010:                    result += "(Prepared) ";
2011:                } else {
2012:                    result += "(Statement) ";
2013:                }
2014:                result += "(";
2015:                StringBuffer buff = new StringBuffer();
2016:                for (int i = 0; i < params.size(); i++) {
2017:                    if (i > 0) {
2018:                        buff.append(", ");
2019:                    }
2020:                    buff.append(((Integer) params.get(i)).intValue() == 0 ? "i"
2021:                            : "rnd");
2022:                }
2023:                result += buff.toString();
2024:                result += ") " + sql;
2025:                return result;
2026:            }
2027:
2028:            private String getHistoryString() {
2029:                StringBuffer buff = new StringBuffer();
2030:                ArrayList history = session.getCommands();
2031:                buff.append("<table cellspacing=0 cellpadding=0>");
2032:                buff.append("<tr><th></th><th>Command</th></tr>");
2033:                for (int i = history.size() - 1; i >= 0; i--) {
2034:                    String sql = (String) history.get(i);
2035:                    buff.append("<tr><td>");
2036:                    buff.append("<a href=\"getHistory.do?id=");
2037:                    buff.append(i);
2038:                    buff
2039:                            .append("&jsessionid=${sessionId}\" target=\"h2query\" ><img width=16 height=16 src=\"ico_write.gif\" onmouseover = \"this.className ='icon_hover'\" onmouseout = \"this.className ='icon'\" class=\"icon\" alt=\"${text.resultEdit.edit}\" title=\"${text.resultEdit.edit}\" border=\"1\"/></a>");
2040:                    buff.append("</td><td>");
2041:                    buff.append(PageParser.escapeHtml(sql));
2042:                    buff.append("</td></tr>");
2043:                }
2044:                buff.append("</table>");
2045:                return buff.toString();
2046:            }
2047:
2048:            private String getParameterResultSet(ParameterMetaData meta)
2049:                    throws SQLException {
2050:                StringBuffer buff = new StringBuffer();
2051:                if (meta == null) {
2052:                    return "No parameter meta data";
2053:                }
2054:                buff.append("<table cellspacing=0 cellpadding=0>");
2055:                buff.append("<tr><th>className</th><th>mode</th><th>type</th>");
2056:                buff
2057:                        .append("<th>typeName</th><th>precision</th><th>scale</th></tr>");
2058:                for (int i = 0; i < meta.getParameterCount(); i++) {
2059:                    buff.append("</tr><td>");
2060:                    buff.append(meta.getParameterClassName(i + 1));
2061:                    buff.append("</td><td>");
2062:                    buff.append(meta.getParameterMode(i + 1));
2063:                    buff.append("</td><td>");
2064:                    buff.append(meta.getParameterType(i + 1));
2065:                    buff.append("</td><td>");
2066:                    buff.append(meta.getParameterTypeName(i + 1));
2067:                    buff.append("</td><td>");
2068:                    buff.append(meta.getPrecision(i + 1));
2069:                    buff.append("</td><td>");
2070:                    buff.append(meta.getScale(i + 1));
2071:                    buff.append("</td></tr>");
2072:                }
2073:                buff.append("</table>");
2074:                return buff.toString();
2075:            }
2076:
2077:            private String getResultSet(String sql, ResultSet rs,
2078:                    boolean metadata, boolean list, boolean edit, long time,
2079:                    boolean allowEdit) throws SQLException {
2080:                int maxrows = getMaxrows();
2081:                time = System.currentTimeMillis() - time;
2082:                StringBuffer buff = new StringBuffer();
2083:                if (edit) {
2084:                    buff
2085:                            .append("<form id=\"editing\" name=\"editing\" method=\"post\" "
2086:                                    + "action=\"editResult.do?jsessionid=${sessionId}\" id=\"mainForm\" target=\"h2result\">");
2087:                    buff
2088:                            .append("<input type=\"hidden\" name=\"op\" value=\"1\" />");
2089:                    buff
2090:                            .append("<input type=\"hidden\" name=\"row\" value=\"\" />");
2091:                    buff
2092:                            .append("<table cellspacing=0 cellpadding=0 id=\"editTable\">");
2093:                } else {
2094:                    buff.append("<table cellspacing=0 cellpadding=0>");
2095:                }
2096:                ResultSetMetaData meta = rs.getMetaData();
2097:                int columns = meta.getColumnCount();
2098:                int rows = 0;
2099:                if (metadata) {
2100:                    buff
2101:                            .append("<tr><th>i</th><th>label</th><th>cat</th><th>schem</th>");
2102:                    buff
2103:                            .append("<th>tab</th><th>col</th><th>type</th><th>typeName</th><th>class</th>");
2104:                    buff
2105:                            .append("<th>prec</th><th>scale</th><th>size</th><th>autoInc</th>");
2106:                    buff
2107:                            .append("<th>case</th><th>currency</th><th>null</th><th>ro</th>");
2108:                    buff
2109:                            .append("<th>search</th><th>sig</th><th>w</th><th>defW</th></tr>");
2110:                    for (int i = 1; i <= columns; i++) {
2111:                        buff.append("<tr>");
2112:                        buff.append("<td>").append(i).append("</td>");
2113:                        buff.append("<td>").append(
2114:                                PageParser.escapeHtml(meta.getColumnLabel(i)))
2115:                                .append("</td>");
2116:                        buff.append("<td>").append(
2117:                                PageParser.escapeHtml(meta.getCatalogName(i)))
2118:                                .append("</td>");
2119:                        buff.append("<td>").append(
2120:                                PageParser.escapeHtml(meta.getSchemaName(i)))
2121:                                .append("</td>");
2122:                        buff.append("<td>").append(
2123:                                PageParser.escapeHtml(meta.getTableName(i)))
2124:                                .append("</td>");
2125:                        buff.append("<td>").append(
2126:                                PageParser.escapeHtml(meta.getColumnName(i)))
2127:                                .append("</td>");
2128:                        buff.append("<td>").append(meta.getColumnType(i))
2129:                                .append("</td>");
2130:                        buff.append("<td>").append(
2131:                                PageParser
2132:                                        .escapeHtml(meta.getColumnTypeName(i)))
2133:                                .append("</td>");
2134:                        buff.append("<td>").append(
2135:                                PageParser.escapeHtml(meta
2136:                                        .getColumnClassName(i)))
2137:                                .append("</td>");
2138:                        buff.append("<td>").append(meta.getPrecision(i))
2139:                                .append("</td>");
2140:                        buff.append("<td>").append(meta.getScale(i)).append(
2141:                                "</td>");
2142:                        buff.append("<td>")
2143:                                .append(meta.getColumnDisplaySize(i)).append(
2144:                                        "</td>");
2145:                        buff.append("<td>").append(meta.isAutoIncrement(i))
2146:                                .append("</td>");
2147:                        buff.append("<td>").append(meta.isCaseSensitive(i))
2148:                                .append("</td>");
2149:                        buff.append("<td>").append(meta.isCurrency(i)).append(
2150:                                "</td>");
2151:                        buff.append("<td>").append(meta.isNullable(i)).append(
2152:                                "</td>");
2153:                        buff.append("<td>").append(meta.isReadOnly(i)).append(
2154:                                "</td>");
2155:                        buff.append("<td>").append(meta.isSearchable(i))
2156:                                .append("</td>");
2157:                        buff.append("<td>").append(meta.isSigned(i)).append(
2158:                                "</td>");
2159:                        buff.append("<td>").append(meta.isWritable(i)).append(
2160:                                "</td>");
2161:                        buff.append("<td>")
2162:                                .append(meta.isDefinitelyWritable(i)).append(
2163:                                        "</td>");
2164:                        buff.append("</tr>");
2165:                    }
2166:                } else if (list) {
2167:                    buff.append("<tr><th>Column</th><th>Data</th></tr><tr>");
2168:                    while (rs.next()) {
2169:                        if (maxrows > 0 && rows >= maxrows) {
2170:                            break;
2171:                        }
2172:                        rows++;
2173:                        buff.append("<tr><td>Row #</td><td>");
2174:                        buff.append(rows);
2175:                        buff.append("</tr>");
2176:                        for (int i = 0; i < columns; i++) {
2177:                            buff.append("<tr><td>");
2178:                            buff.append(PageParser.escapeHtml(meta
2179:                                    .getColumnLabel(i + 1)));
2180:                            buff.append("</td>");
2181:                            buff.append("<td>");
2182:                            buff.append(escapeData(rs.getString(i + 1)));
2183:                            buff.append("</td></tr>");
2184:                        }
2185:                    }
2186:                } else {
2187:                    buff.append("<tr>");
2188:                    if (edit) {
2189:                        buff.append("<th>Action</th>");
2190:                    }
2191:                    for (int i = 0; i < columns; i++) {
2192:                        buff.append("<th>");
2193:                        buff.append(PageParser.escapeHtml(meta
2194:                                .getColumnLabel(i + 1)));
2195:                        buff.append("</th>");
2196:                    }
2197:                    buff.append("</tr>");
2198:                    while (rs.next()) {
2199:                        if (maxrows > 0 && rows >= maxrows) {
2200:                            break;
2201:                        }
2202:                        rows++;
2203:                        buff.append("<tr>");
2204:                        if (edit) {
2205:                            buff.append("<td>");
2206:                            buff.append("<img onclick=\"javascript:editRow(");
2207:                            buff.append(rs.getRow());
2208:                            buff
2209:                                    .append(",'${sessionId}', '${text.resultEdit.save}', '${text.resultEdit.cancel}'");
2210:                            buff
2211:                                    .append(")\" width=16 height=16 src=\"ico_write.gif\" onmouseover = \"this.className ='icon_hover'\" onmouseout = \"this.className ='icon'\" class=\"icon\" alt=\"${text.resultEdit.edit}\" title=\"${text.resultEdit.edit}\" border=\"1\"/>");
2212:                            buff.append("<a href=\"editResult.do?op=2&row=");
2213:                            buff.append(rs.getRow());
2214:                            buff
2215:                                    .append("&jsessionid=${sessionId}\" target=\"h2result\" ><img width=16 height=16 src=\"ico_remove.gif\" onmouseover = \"this.className ='icon_hover'\" onmouseout = \"this.className ='icon'\" class=\"icon\" alt=\"${text.resultEdit.delete}\" title=\"${text.resultEdit.delete}\" border=\"1\" /></a>");
2216:                            buff.append("</td>");
2217:                        }
2218:                        for (int i = 0; i < columns; i++) {
2219:                            buff.append("<td>");
2220:                            buff.append(escapeData(rs.getString(i + 1)));
2221:                            buff.append("</td>");
2222:                        }
2223:                        buff.append("</tr>");
2224:                    }
2225:                }
2226:                boolean isUpdatable = rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE
2227:                        && rs.getType() != ResultSet.TYPE_FORWARD_ONLY;
2228:                if (edit) {
2229:                    ResultSet old = session.result;
2230:                    if (old != null) {
2231:                        old.close();
2232:                    }
2233:                    session.result = rs;
2234:                } else {
2235:                    rs.close();
2236:                }
2237:                if (edit) {
2238:                    buff.append("<tr><td>");
2239:                    buff
2240:                            .append("<img onclick=\"javascript:editRow(-1, '${sessionId}', '${text.resultEdit.save}', '${text.resultEdit.cancel}'");
2241:                    buff
2242:                            .append(")\" width=16 height=16 src=\"ico_add.gif\" onmouseover = \"this.className ='icon_hover'\" onmouseout = \"this.className ='icon'\" class=\"icon\" alt=\"${text.resultEdit.add}\" title=\"${text.resultEdit.add}\" border=\"1\"/>");
2243:                    buff.append("</td>");
2244:                    for (int i = 0; i < columns; i++) {
2245:                        buff.append("<td></td>");
2246:                    }
2247:                    buff.append("</tr>");
2248:                }
2249:                buff.append("</table>");
2250:                if (edit) {
2251:                    buff.append("</form>");
2252:                }
2253:                if (rows == 0) {
2254:                    buff.append("(${text.result.noRows}");
2255:                } else if (rows == 1) {
2256:                    buff.append("(${text.result.1row}");
2257:                } else {
2258:                    buff.append("(");
2259:                    buff.append(rows);
2260:                    buff.append(" ${text.result.rows}");
2261:                }
2262:                buff.append(", ");
2263:                time = System.currentTimeMillis() - time;
2264:                buff.append(time);
2265:                buff.append(" ms)");
2266:                if (!edit && isUpdatable && allowEdit) {
2267:                    buff
2268:                            .append("<br /><br /><form name=\"editResult\" method=\"post\" action=\"query.do?jsessionid=${sessionId}\" target=\"h2result\">");
2269:                    buff
2270:                            .append("<input type=\"submit\" class=\"button\" value=\"${text.resultEdit.editResult}\" />");
2271:                    buff
2272:                            .append("<input type=\"hidden\" name=\"sql\" value=\"@EDIT "
2273:                                    + PageParser.escapeHtml(sql) + "\" />");
2274:                    buff.append("</form>");
2275:                }
2276:                return buff.toString();
2277:            }
2278:
2279:            private String settingSave() {
2280:                ConnectionInfo info = new ConnectionInfo();
2281:                info.name = attributes.getProperty("name", "");
2282:                info.driver = attributes.getProperty("driver", "");
2283:                info.url = attributes.getProperty("url", "");
2284:                info.user = attributes.getProperty("user", "");
2285:                server.updateSetting(info);
2286:                attributes.put("setting", info.name);
2287:                server.saveSettings();
2288:                return "index.do";
2289:            }
2290:
2291:            private String escapeData(String d) {
2292:                if (d == null) {
2293:                    return "<i>null</i>";
2294:                } else if (d.startsWith("null")) {
2295:                    return "<div style='display: none'>=</div>"
2296:                            + PageParser.escapeHtml(d);
2297:                }
2298:                return PageParser.escapeHtml(d);
2299:            }
2300:
2301:            private String unescapeData(String d) {
2302:                if (d.endsWith("null")) {
2303:                    if (d.equals("null")) {
2304:                        return null;
2305:                    } else if (d.startsWith("=")) {
2306:                        return d.substring(1);
2307:                    }
2308:                }
2309:                return d;
2310:            }
2311:
2312:            private String settingRemove() {
2313:                String setting = attributes.getProperty("name", "");
2314:                server.removeSetting(setting);
2315:                ArrayList settings = server.getSettings();
2316:                if (settings.size() > 0) {
2317:                    attributes.put("setting", settings.get(0));
2318:                }
2319:                server.saveSettings();
2320:                return "index.do";
2321:            }
2322:
2323:            boolean allow() {
2324:                if (server.getAllowOthers()) {
2325:                    return true;
2326:                }
2327:                return NetUtils.isLoopbackAddress(socket);
2328:            }
2329:
2330:            public String getMimeType() {
2331:                return mimeType;
2332:            }
2333:
2334:            public boolean getCache() {
2335:                return cache;
2336:            }
2337:
2338:            public WebSession getSession() {
2339:                return session;
2340:            }
2341:
2342:            public void closingDatabase() {
2343:                log("Closing database");
2344:            }
2345:
2346:            public void diskSpaceIsLow(long stillAvailable) throws SQLException {
2347:                log("Disk space is low; still available: " + stillAvailable);
2348:            }
2349:
2350:            public void exceptionThrown(SQLException e, String sql) {
2351:                log("Exception: " + e.toString() + " SQL: " + sql);
2352:            }
2353:
2354:            public void init(String url) {
2355:                log("Init: " + url);
2356:            }
2357:
2358:            public void opened() {
2359:                log("Database was opened");
2360:            }
2361:
2362:            public void setProgress(int state, String name, int x, int max) {
2363:                if (state == listenerLastState) {
2364:                    long time = System.currentTimeMillis();
2365:                    if (listenerLastEvent + 500 < time) {
2366:                        return;
2367:                    }
2368:                    listenerLastEvent = time;
2369:                } else {
2370:                    listenerLastState = state;
2371:                }
2372:                switch (state) {
2373:                case DatabaseEventListener.STATE_BACKUP_FILE:
2374:                    log("Backing up " + name + " " + (100L * x / max) + "%");
2375:                    break;
2376:                case DatabaseEventListener.STATE_CREATE_INDEX:
2377:                    log("Creating index " + name + " " + (100L * x / max) + "%");
2378:                    break;
2379:                case DatabaseEventListener.STATE_RECOVER:
2380:                    log("Recovering " + name + " " + (100L * x / max) + "%");
2381:                    break;
2382:                case DatabaseEventListener.STATE_SCAN_FILE:
2383:                    log("Scanning file " + name + " " + (100L * x / max) + "%");
2384:                    break;
2385:                default:
2386:                    log("Unknown state: " + state);
2387:                }
2388:            }
2389:
2390:            private void log(String s) {
2391:                // System.out.println(s);
2392:            }
2393:
2394:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.