JPA包装器将未经检查的异常转换为已检查的异常?

时间:2010-11-17 18:52:49

标签: java jpa

在我徘徊并重新创建轮子之前,是否有人知道JPA包装器将JPA抛出的未经检查的异常转换为已检查的异常?

没有找到关于为什么我不想要检查异常的论据,我确实想要它们: - )

1 个答案:

答案 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);
    }
}
}