11.10 Map
This commit is contained in:
11
src/annotations/database/Constraints.java
Normal file
11
src/annotations/database/Constraints.java
Normal file
@@ -0,0 +1,11 @@
|
||||
//: annotations/database/Constraints.java
|
||||
package annotations.database;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Constraints {
|
||||
boolean primaryKey() default false;
|
||||
boolean allowNull() default true;
|
||||
boolean unique() default false;
|
||||
} ///:~
|
||||
9
src/annotations/database/DBTable.java
Normal file
9
src/annotations/database/DBTable.java
Normal file
@@ -0,0 +1,9 @@
|
||||
//: annotations/database/DBTable.java
|
||||
package annotations.database;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE) // Applies to classes only
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DBTable {
|
||||
public String name() default "";
|
||||
} ///:~
|
||||
18
src/annotations/database/Member.java
Normal file
18
src/annotations/database/Member.java
Normal file
@@ -0,0 +1,18 @@
|
||||
//: annotations/database/Member.java
|
||||
package annotations.database;
|
||||
|
||||
@DBTable(name = "MEMBER")
|
||||
public class Member {
|
||||
@SQLString(30) String firstName;
|
||||
@SQLString(50) String lastName;
|
||||
@SQLInteger Integer age;
|
||||
@SQLString(value = 30,
|
||||
constraints = @Constraints(primaryKey = true))
|
||||
String handle;
|
||||
static int memberCount;
|
||||
public String getHandle() { return handle; }
|
||||
public String getFirstName() { return firstName; }
|
||||
public String getLastName() { return lastName; }
|
||||
public String toString() { return handle; }
|
||||
public Integer getAge() { return age; }
|
||||
} ///:~
|
||||
10
src/annotations/database/SQLInteger.java
Normal file
10
src/annotations/database/SQLInteger.java
Normal file
@@ -0,0 +1,10 @@
|
||||
//: annotations/database/SQLInteger.java
|
||||
package annotations.database;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SQLInteger {
|
||||
String name() default "";
|
||||
Constraints constraints() default @Constraints;
|
||||
} ///:~
|
||||
11
src/annotations/database/SQLString.java
Normal file
11
src/annotations/database/SQLString.java
Normal file
@@ -0,0 +1,11 @@
|
||||
//: annotations/database/SQLString.java
|
||||
package annotations.database;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SQLString {
|
||||
int value() default 0;
|
||||
String name() default "";
|
||||
Constraints constraints() default @Constraints;
|
||||
} ///:~
|
||||
105
src/annotations/database/TableCreationProcessorFactory.java
Normal file
105
src/annotations/database/TableCreationProcessorFactory.java
Normal file
@@ -0,0 +1,105 @@
|
||||
//: annotations/database/TableCreationProcessorFactory.java
|
||||
// The database example using Visitor.
|
||||
// {Exec: apt -factory
|
||||
// annotations.database.TableCreationProcessorFactory
|
||||
// database/Member.java -s database}
|
||||
package annotations.database;
|
||||
import com.sun.mirror.apt.*;
|
||||
import com.sun.mirror.declaration.*;
|
||||
import com.sun.mirror.util.*;
|
||||
import java.util.*;
|
||||
import static com.sun.mirror.util.DeclarationVisitors.*;
|
||||
|
||||
public class TableCreationProcessorFactory
|
||||
implements AnnotationProcessorFactory {
|
||||
public AnnotationProcessor getProcessorFor(
|
||||
Set<AnnotationTypeDeclaration> atds,
|
||||
AnnotationProcessorEnvironment env) {
|
||||
return new TableCreationProcessor(env);
|
||||
}
|
||||
public Collection<String> supportedAnnotationTypes() {
|
||||
return Arrays.asList(
|
||||
"annotations.database.DBTable",
|
||||
"annotations.database.Constraints",
|
||||
"annotations.database.SQLString",
|
||||
"annotations.database.SQLInteger");
|
||||
}
|
||||
public Collection<String> supportedOptions() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
private static class TableCreationProcessor
|
||||
implements AnnotationProcessor {
|
||||
private final AnnotationProcessorEnvironment env;
|
||||
private String sql = "";
|
||||
public TableCreationProcessor(
|
||||
AnnotationProcessorEnvironment env) {
|
||||
this.env = env;
|
||||
}
|
||||
public void process() {
|
||||
for(TypeDeclaration typeDecl :
|
||||
env.getSpecifiedTypeDeclarations()) {
|
||||
typeDecl.accept(getDeclarationScanner(
|
||||
new TableCreationVisitor(), NO_OP));
|
||||
sql = sql.substring(0, sql.length() - 1) + ");";
|
||||
System.out.println("creation SQL is :\n" + sql);
|
||||
sql = "";
|
||||
}
|
||||
}
|
||||
private class TableCreationVisitor
|
||||
extends SimpleDeclarationVisitor {
|
||||
public void visitClassDeclaration(
|
||||
ClassDeclaration d) {
|
||||
DBTable dbTable = d.getAnnotation(DBTable.class);
|
||||
if(dbTable != null) {
|
||||
sql += "CREATE TABLE ";
|
||||
sql += (dbTable.name().length() < 1)
|
||||
? d.getSimpleName().toUpperCase()
|
||||
: dbTable.name();
|
||||
sql += " (";
|
||||
}
|
||||
}
|
||||
public void visitFieldDeclaration(
|
||||
FieldDeclaration d) {
|
||||
String columnName = "";
|
||||
if(d.getAnnotation(SQLInteger.class) != null) {
|
||||
SQLInteger sInt = d.getAnnotation(
|
||||
SQLInteger.class);
|
||||
// Use field name if name not specified
|
||||
if(sInt.name().length() < 1) {
|
||||
columnName = d.getSimpleName().toUpperCase();
|
||||
} else {
|
||||
columnName = sInt.name();
|
||||
}
|
||||
sql += "\n " + columnName + " INT" +
|
||||
getConstraints(sInt.constraints()) + ",";
|
||||
}
|
||||
if(d.getAnnotation(SQLString.class) != null) {
|
||||
SQLString sString = d.getAnnotation(
|
||||
SQLString.class);
|
||||
// Use field name if name not specified.
|
||||
if(sString.name().length() < 1) {
|
||||
columnName = d.getSimpleName().toUpperCase();
|
||||
} else {
|
||||
columnName = sString.name();
|
||||
}
|
||||
sql += "\n " + columnName + " VARCHAR(" +
|
||||
sString.value() + ")" +
|
||||
getConstraints(sString.constraints()) + ",";
|
||||
}
|
||||
}
|
||||
private String getConstraints(Constraints con) {
|
||||
String constraints = "";
|
||||
if(!con.allowNull()) {
|
||||
constraints += " NOT NULL";
|
||||
}
|
||||
if(con.primaryKey()) {
|
||||
constraints += " PRIMARY KEY";
|
||||
}
|
||||
if(con.unique()) {
|
||||
constraints += " UNIQUE";
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
}
|
||||
}
|
||||
} ///:~
|
||||
103
src/annotations/database/TableCreator.java
Normal file
103
src/annotations/database/TableCreator.java
Normal file
@@ -0,0 +1,103 @@
|
||||
//: annotations/database/TableCreator.java
|
||||
// Reflection-based annotation processor.
|
||||
// {Args: annotations.database.Member}
|
||||
package annotations.database;
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
public class TableCreator {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if(args.length < 1) {
|
||||
System.out.println("arguments: annotated classes");
|
||||
System.exit(0);
|
||||
}
|
||||
for(String className : args) {
|
||||
Class<?> cl = Class.forName(className);
|
||||
DBTable dbTable = cl.getAnnotation(DBTable.class);
|
||||
if(dbTable == null) {
|
||||
System.out.println(
|
||||
"No DBTable annotations in class " + className);
|
||||
continue;
|
||||
}
|
||||
String tableName = dbTable.name();
|
||||
// If the name is empty, use the Class name:
|
||||
if(tableName.length() < 1) {
|
||||
tableName = cl.getName().toUpperCase();
|
||||
}
|
||||
List<String> columnDefs = new ArrayList<String>();
|
||||
for(Field field : cl.getDeclaredFields()) {
|
||||
String columnName = null;
|
||||
Annotation[] anns = field.getDeclaredAnnotations();
|
||||
if(anns.length < 1) {
|
||||
continue; // Not a db table column
|
||||
}
|
||||
if(anns[0] instanceof SQLInteger) {
|
||||
SQLInteger sInt = (SQLInteger) anns[0];
|
||||
// Use field name if name not specified
|
||||
if(sInt.name().length() < 1) {
|
||||
columnName = field.getName().toUpperCase();
|
||||
} else {
|
||||
columnName = sInt.name();
|
||||
}
|
||||
columnDefs.add(columnName + " INT" +
|
||||
getConstraints(sInt.constraints()));
|
||||
}
|
||||
if(anns[0] instanceof SQLString) {
|
||||
SQLString sString = (SQLString) anns[0];
|
||||
// Use field name if name not specified.
|
||||
if(sString.name().length() < 1) {
|
||||
columnName = field.getName().toUpperCase();
|
||||
} else {
|
||||
columnName = sString.name();
|
||||
}
|
||||
columnDefs.add(columnName + " VARCHAR(" +
|
||||
sString.value() + ")" +
|
||||
getConstraints(sString.constraints()));
|
||||
}
|
||||
StringBuilder createCommand = new StringBuilder(
|
||||
"CREATE TABLE " + tableName + "(");
|
||||
for(String columnDef : columnDefs) {
|
||||
createCommand.append("\n " + columnDef + ",");
|
||||
}
|
||||
// Remove trailing comma
|
||||
String tableCreate = createCommand.substring(
|
||||
0, createCommand.length() - 1) + ");";
|
||||
System.out.println("Table Creation SQL for " +
|
||||
className + " is :\n" + tableCreate);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static String getConstraints(Constraints con) {
|
||||
String constraints = "";
|
||||
if(!con.allowNull()) {
|
||||
constraints += " NOT NULL";
|
||||
}
|
||||
if(con.primaryKey()) {
|
||||
constraints += " PRIMARY KEY";
|
||||
}
|
||||
if(con.unique()) {
|
||||
constraints += " UNIQUE";
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
} /* Output:
|
||||
Table Creation SQL for annotations.database.Member is :
|
||||
CREATE TABLE MEMBER(
|
||||
FIRSTNAME VARCHAR(30));
|
||||
Table Creation SQL for annotations.database.Member is :
|
||||
CREATE TABLE MEMBER(
|
||||
FIRSTNAME VARCHAR(30),
|
||||
LASTNAME VARCHAR(50));
|
||||
Table Creation SQL for annotations.database.Member is :
|
||||
CREATE TABLE MEMBER(
|
||||
FIRSTNAME VARCHAR(30),
|
||||
LASTNAME VARCHAR(50),
|
||||
AGE INT);
|
||||
Table Creation SQL for annotations.database.Member is :
|
||||
CREATE TABLE MEMBER(
|
||||
FIRSTNAME VARCHAR(30),
|
||||
LASTNAME VARCHAR(50),
|
||||
AGE INT,
|
||||
HANDLE VARCHAR(30) PRIMARY KEY);
|
||||
*///:~
|
||||
8
src/annotations/database/Uniqueness.java
Normal file
8
src/annotations/database/Uniqueness.java
Normal file
@@ -0,0 +1,8 @@
|
||||
//: annotations/database/Uniqueness.java
|
||||
// Sample of nested annotations
|
||||
package annotations.database;
|
||||
|
||||
public @interface Uniqueness {
|
||||
Constraints constraints()
|
||||
default @Constraints(unique=true);
|
||||
} ///:~
|
||||
Reference in New Issue
Block a user