Updating to NBMs from NetBeans 8.0.1 as some of them are required to run on JDK8
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.DatabaseMetaData;
8 import java.sql.Driver;
9 import java.sql.ResultSet;
10 import java.sql.ResultSetMetaData;
11 import java.sql.SQLException;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 import java.util.Map.Entry;
16 import java.util.Properties;
17 import java.util.ServiceLoader;
19 import javax.annotation.processing.AbstractProcessor;
20 import javax.annotation.processing.Completion;
21 import javax.annotation.processing.Completions;
22 import javax.annotation.processing.Filer;
23 import javax.annotation.processing.Processor;
24 import javax.annotation.processing.RoundEnvironment;
25 import javax.annotation.processing.SupportedAnnotationTypes;
26 import javax.annotation.processing.SupportedSourceVersion;
27 import javax.lang.model.SourceVersion;
28 import javax.lang.model.element.AnnotationMirror;
29 import javax.lang.model.element.AnnotationValue;
30 import javax.lang.model.element.Element;
31 import javax.lang.model.element.ExecutableElement;
32 import javax.lang.model.element.PackageElement;
33 import javax.lang.model.element.TypeElement;
34 import javax.tools.JavaFileObject;
35 import org.apidesign.livedb.LiveDB;
36 import org.openide.util.lookup.ServiceProvider;
40 * @author Jaroslav Tulach <jtulach@netbeans.org>
42 // BEGIN: livedb.processor
43 @SupportedAnnotationTypes("org.apidesign.livedb.LiveDB")
44 @SupportedSourceVersion(SourceVersion.RELEASE_6)
45 @ServiceProvider(service=Processor.class)
46 public final class LiveDBProcessor extends AbstractProcessor {
48 public boolean process(
49 Set<? extends TypeElement> annotations, RoundEnvironment roundEnv
51 final Filer filer = processingEnv.getFiler();
52 for (Element e : roundEnv.getElementsAnnotatedWith(LiveDB.class)) {
53 LiveDB db = e.getAnnotation(LiveDB.class);
54 PackageElement pe = (PackageElement)e;
55 String clsName = pe.getQualifiedName() + "." + db.classname();
57 JavaFileObject src = filer.createSourceFile(clsName, pe);
58 Writer w = src.openWriter();
59 Connection c = getConnection(
60 db.url(), db.user(), db.password()
62 CallableStatement s = c.prepareCall(db.query());
63 ResultSet rs = s.executeQuery();
64 ResultSetMetaData md = rs.getMetaData();
65 generateClassHeader(w, pe, db);
66 w.append("class " + db.classname() + " {\n");
67 for (int i = 1; i <= md.getColumnCount(); i++) {
68 generateField(w, md, i);
70 generateConstructor(w, db, md);
71 generateQueryMethod(w, db, md);
74 } catch (IOException ex) {
75 throw new IllegalStateException(ex);
76 } catch (SQLException ex) {
77 throw new IllegalStateException(ex);
82 // FINISH: livedb.processor
84 private void generateQueryMethod(Writer w, LiveDB db, ResultSetMetaData md) throws SQLException, IOException {
85 w.append(" public static List<" + db.classname() + "> ")
86 .append("query() throws SQLException {\n");
87 w.append(" Connection c = DriverManager.getConnection(\"")
88 .append(db.url()).append("\", \"")
89 .append(db.user()).append("\", \"")
90 .append(db.password()).append("\");\n");
91 w.append(" List<").append(db.classname())
92 .append("> res = new ArrayList<")
93 .append(db.classname()).append(">();\n");
94 w.append(" CallableStatement s = c.prepareCall(\"")
95 .append(db.query()).append("\");\n");
96 w.append(" ResultSet rs = s.executeQuery();\n");
97 w.append(" ResultSetMetaData md = rs.getMetaData();\n");
98 w.append(" while (rs.next()) {\n");
99 w.append(" res.add(new " + db.classname() + "(\n");
100 for (int i = 1; i <= md.getColumnCount(); i++) {
102 .append(md.getColumnClassName(i))
103 .append(")rs.getObject(" + i).append(")");
104 if (i < md.getColumnCount()) {
112 w.append(" return res;\n");
116 private void generateConstructor(Writer w, LiveDB db, ResultSetMetaData md) throws SQLException, IOException {
117 w.append(" private " + db.classname() + "(\n");
118 for (int i = 1; i <= md.getColumnCount(); i++) {
119 w.append(" ").append(md.getColumnClassName(i))
120 .append(" ").append(md.getColumnName(i));
121 if (i < md.getColumnCount()) {
128 for (int i = 1; i <= md.getColumnCount(); i++) {
130 .append(md.getColumnName(i))
132 .append(md.getColumnName(i))
138 private void generateField(Writer w, ResultSetMetaData md, int i) throws IOException, SQLException {
139 w.append(" public final ")
140 .append(md.getColumnClassName(i))
142 .append(md.getColumnName(i))
146 private void generateClassHeader(Writer w, PackageElement pe, LiveDB db) throws IOException {
147 w.append("package " + pe.getQualifiedName() + ";\n");
148 w.append("import java.util.List;\n");
149 w.append("import java.util.ArrayList;\n");
150 w.append("import java.sql.*;\n");
152 private static Connection getConnection(String url, String user, String password)
153 throws SQLException {
154 final ClassLoader cl = LiveDBProcessor.class.getClassLoader();
155 for (Driver d : ServiceLoader.load(Driver.class, cl)) {
156 // System.out.println("looked up: " + d);
157 if (d.acceptsURL(url)) {
158 //System.out.println("accepts: " + d);
159 Properties p = new Properties();
161 p.put("password", password);
162 return d.connect(url, p);
165 throw new SQLException("No driver found for " + url);
170 // BEGIN: livedb.completions
172 public Iterable<? extends Completion> getCompletions(
173 Element element, AnnotationMirror annotation,
174 ExecutableElement member, String userText
176 if (!"query".equals(member.getSimpleName().toString())) {
177 return Collections.emptyList();
179 if (userText == null || userText.length() <= 1) {
180 return Collections.singleton(Completions.of("\"SELECT "));
182 if (userText.toUpperCase().matches(".*FROM *")) {
183 String user = extractValue(annotation, "user");
184 String password = extractValue(annotation, "password");
185 String url = extractValue(annotation, "url");
186 if (user == null || password == null || url == null) {
187 return Collections.emptyList();
190 List<Completion> arr = new ArrayList<Completion>();
191 Connection c = getConnection(url, user, password);
192 DatabaseMetaData meta = c.getMetaData();
193 ResultSet res = meta.getTables(null, null, "%", null);
194 boolean ok = res.first();
196 String txt = userText + res.getString("TABLE_NAME");
197 arr.add(Completions.of(txt));
201 } catch (SQLException ex) {
202 throw new IllegalStateException(ex);
205 return Collections.emptyList();
207 // END: livedb.completions
209 private static String extractValue(AnnotationMirror am, String param) {
210 AnnotationValue av = null;
211 for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : am.getElementValues().entrySet()) {
212 if (entry.getKey().toString().equals(param + "()")) {
213 av = entry.getValue();
220 String s = av.toString();
221 if (s.startsWith("\"")) {
224 if (s.endsWith("\"")) {
225 s = s.substring(0, s.length() - 1);