1 package org.apidesign.livedb.impl;
3 import java.io.IOException;
5 import java.sql.CallableStatement;
6 import java.sql.Connection;
7 import java.sql.Driver;
8 import java.sql.ResultSet;
9 import java.sql.ResultSetMetaData;
10 import java.sql.SQLException;
11 import java.util.Properties;
12 import java.util.ServiceLoader;
14 import javax.annotation.processing.AbstractProcessor;
15 import javax.annotation.processing.Filer;
16 import javax.annotation.processing.Processor;
17 import javax.annotation.processing.RoundEnvironment;
18 import javax.annotation.processing.SupportedAnnotationTypes;
19 import javax.annotation.processing.SupportedSourceVersion;
20 import javax.lang.model.SourceVersion;
21 import javax.lang.model.element.Element;
22 import javax.lang.model.element.PackageElement;
23 import javax.lang.model.element.TypeElement;
24 import javax.tools.JavaFileObject;
25 import org.apidesign.livedb.LiveDB;
26 import org.openide.util.lookup.ServiceProvider;
30 * @author Jaroslav Tulach <jtulach@netbeans.org>
32 // BEGIN: livedb.processor
33 @SupportedAnnotationTypes("org.apidesign.livedb.LiveDB")
34 @SupportedSourceVersion(SourceVersion.RELEASE_6)
35 @ServiceProvider(service=Processor.class)
36 public final class LiveDBProcessor extends AbstractProcessor {
38 public boolean process(
39 Set<? extends TypeElement> annotations, RoundEnvironment roundEnv
41 final Filer filer = processingEnv.getFiler();
42 for (Element e : roundEnv.getElementsAnnotatedWith(LiveDB.class)) {
43 LiveDB db = e.getAnnotation(LiveDB.class);
44 PackageElement pe = (PackageElement)e;
45 String clsName = pe.getQualifiedName() + "." + db.classname();
47 JavaFileObject src = filer.createSourceFile(clsName, pe);
48 Writer w = src.openWriter();
49 Connection c = getConnection(
50 db.url(), db.user(), db.password()
52 CallableStatement s = c.prepareCall(db.query());
53 ResultSet rs = s.executeQuery();
54 ResultSetMetaData md = rs.getMetaData();
55 generateClassHeader(w, pe, db);
56 w.append("class " + db.classname() + " {\n");
57 for (int i = 1; i <= md.getColumnCount(); i++) {
58 generateField(w, md, i);
60 generateConstructor(w, db, md);
61 generateQueryMethod(w, db, md);
64 } catch (IOException ex) {
65 throw new IllegalStateException(ex);
66 } catch (SQLException ex) {
67 throw new IllegalStateException(ex);
72 // FINISH: livedb.processor
74 private void generateQueryMethod(Writer w, LiveDB db, ResultSetMetaData md) throws SQLException, IOException {
75 w.append(" public static List<" + db.classname() + "> ")
76 .append("query() throws SQLException {\n");
77 w.append(" Connection c = DriverManager.getConnection(\"")
78 .append(db.url()).append("\", \"")
79 .append(db.user()).append("\", \"")
80 .append(db.password()).append("\");\n");
81 w.append(" List<").append(db.classname())
82 .append("> res = new ArrayList<")
83 .append(db.classname()).append(">();\n");
84 w.append(" CallableStatement s = c.prepareCall(\"")
85 .append(db.query()).append("\");\n");
86 w.append(" ResultSet rs = s.executeQuery();\n");
87 w.append(" ResultSetMetaData md = rs.getMetaData();\n");
88 w.append(" while (rs.next()) {\n");
89 w.append(" res.add(new " + db.classname() + "(\n");
90 for (int i = 1; i <= md.getColumnCount(); i++) {
92 .append(md.getColumnClassName(i))
93 .append(")rs.getObject(" + i).append(")");
94 if (i < md.getColumnCount()) {
102 w.append(" return res;\n");
106 private void generateConstructor(Writer w, LiveDB db, ResultSetMetaData md) throws SQLException, IOException {
107 w.append(" private " + db.classname() + "(\n");
108 for (int i = 1; i <= md.getColumnCount(); i++) {
109 w.append(" ").append(md.getColumnClassName(i))
110 .append(" ").append(md.getColumnName(i));
111 if (i < md.getColumnCount()) {
118 for (int i = 1; i <= md.getColumnCount(); i++) {
120 .append(md.getColumnName(i))
122 .append(md.getColumnName(i))
128 private void generateField(Writer w, ResultSetMetaData md, int i) throws IOException, SQLException {
129 w.append(" public final ")
130 .append(md.getColumnClassName(i))
132 .append(md.getColumnName(i))
136 private void generateClassHeader(Writer w, PackageElement pe, LiveDB db) throws IOException {
137 w.append("package " + pe.getQualifiedName() + ";\n");
138 w.append("import java.util.List;\n");
139 w.append("import java.util.ArrayList;\n");
140 w.append("import java.sql.*;\n");
142 private static Connection getConnection(String url, String user, String password)
143 throws SQLException {
144 final ClassLoader cl = LiveDBProcessor.class.getClassLoader();
145 for (Driver d : ServiceLoader.load(Driver.class, cl)) {
146 // System.out.println("looked up: " + d);
147 if (d.acceptsURL(url)) {
148 //System.out.println("accepts: " + d);
149 Properties p = new Properties();
151 p.put("password", password);
152 return d.connect(url, p);
155 throw new SQLException("No driver found for " + url);