在我徘徊并重新创建轮子之前,是否有人知道JPA包装器将JPA抛出的未经检查的异常转换为已检查的异常?
没有找到关于为什么我不想要检查异常的论据,我确实想要它们: - )
答案 0 :(得分:1)
您可以使用以下代码完成99%的自行滚动。由于需要封装Collection的成员,它会给你带来两个编译错误,但它确实会让你超过它不再值得自动化的地步。
package so;
import javax.persistence.*;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.*;
public class CheckedPersistenceMaker {
static final String PACKAGE = "stackoverflow.javax.persistence";
static final String PACKAGE_DIR = PACKAGE.replace('.', '/');
static Class<?>[] CLASSES = new Class<?>[] { Cache.class,
EntityManager.class, EntityManagerFactory.class,
EntityTransaction.class, Parameter.class,
PersistenceUnitUtil.class, PersistenceUtil.class,
Persistence.class, Query.class, Tuple.class, TupleElement.class,
TypedQuery.class };
private static String getName(Class<?> c) {
String name = c.getName();
for(Class<?> p:CLASSES) {
if (p.equals(c))
return PACKAGE + ".Checked"
+ name.substring(name.lastIndexOf('.') + 1);
}
return c.getName();
}
static void generateWrapper(Class<?> c) throws Exception {
String name = c.getName();
TypeVariable<?>[] genType = c.getTypeParameters();
String varNames = "";
if (genType != null && genType.length != 0) {
StringBuilder b = new StringBuilder();
b.append("<");
for(int i = 0;i < genType.length;i++) {
if (i > 0) b.append(",");
b.append(genType[i].getName());
}
b.append(">");
varNames = b.toString();
}
name = "Checked" + name.substring(name.lastIndexOf('.') + 1);
File javaFile = new File(PACKAGE_DIR + "/" + name + ".java");
javaFile.getParentFile().mkdirs();
FileWriter w = new FileWriter(javaFile);
w.write("package " + PACKAGE + ";\n");
w.write("public class " + name + varNames + " {\n");
w.write(" private final " + c.getName() + varNames
+ " wrapped;\n\n ");
w.write(name + "(" + c.getName() + varNames
+ " original) {\nwrapped=original;\n}\n\n");
w.write(" public " + c.getName() + varNames
+ " getOriginal() { return wrapped; }\n\n");
Method[] ms = c.getDeclaredMethods();
for(Method m:ms) {
if (!Modifier.isPublic(m.getModifiers())) continue;
w.write(" ");
String s = m.toGenericString();
s = s.replace(" abstract ", " ");
s = s.replace(c.getName() + ".", "");
String q = s.substring(0, s.indexOf('('));
if (q.indexOf('<',10) != -1) q = q.substring(0, q.indexOf('<',10));
boolean needsTranslate = false;
for(Class<?> cc:CLASSES) {
String ccn = cc.getName();
if (q.indexOf(ccn) != -1) needsTranslate = true;
String ccc = ccn.replace(cc.getPackage().getName() + ".",
PACKAGE + ".Checked");
s = s.replace(ccn, ccc);
}
int pc = 0;
int p = s.indexOf('(');
if (s.charAt(p + 1) != ')') {
StringBuilder b = new StringBuilder(s);
int g = 0;
char ch;
do {
ch = b.charAt(p);
switch (ch) {
case '<': {
g++;
break;
}
case '>': {
g--;
break;
}
case ',':
case ')': {
if (g == 0) {
String pa = " p" + pc;
b.insert(p, pa);
pc++;
p += pa.length();
}
break;
}
}
p++;
} while( ch != ')' );
s = b.toString();
}
w.write(s);
w.write(" throws CheckedPersistenceException");
Class<?>[] excs = m.getExceptionTypes();
for(Class<?> e:excs) {
w.write(", " + e.getName());
}
w.write(" {\n try {\n ");
Class<?> ret = m.getReturnType();
if (!ret.equals(Void.TYPE)) {
w.write("return ");
if (needsTranslate) {
String retName = ret.getName();
retName = retName.replace(c.getPackage().getName() + ".",
PACKAGE + ".Checked");
w.write("new " + retName + "(");
}
}
if (Modifier.isStatic(m.getModifiers())) {
w.write(c.getName() + "." + m.getName() + "(");
} else {
w.write("wrapped." + m.getName() + "(");
}
Class<?> paramTypes[] = m.getParameterTypes();
for(int i = 0;i < pc;i++) {
if (i > 0) w.write(',');
boolean isChecked = false;
for(int j=0;j<CLASSES.length;j++) {
if( CLASSES[j].equals(paramTypes[i]) ) isChecked=true;
}
w.write("p" + i);
if(isChecked) w.write(".getOriginal()");
}
w.write(')');
if (needsTranslate) w.write(')');
w.write(";\n } catch ( javax.persistence.PersistenceException e ) { throw new CheckedPersistenceException(e); }\n }\n\n");
}
w.write("}\n");
w.close();
}
public static void main(String[] args) throws Exception {
for(Class<?> c:CLASSES) {
generateWrapper(c);
}
}
}