2010-11-17 60 views
3

在我漫步并重新创建轮子之前,有没有人知道JPA封装器会将未检查的异常转换为已检查的异常?JPA包装将未检查的异常转换为检查的异常?

不找我为什么不应该要检查的异常的说法,我也希望他们:-)

+0

仍然,你为什么要这么做?如果没有这样的包装,也许有一个原因背后呢? :-P – 2010-11-17 19:05:56

+0

'大多数人不像我对异常的挑剔一样? :-) – TofuBeer 2010-11-17 19:43:41

+0

你最终滚了你自己的?小心分享? – 2011-04-01 08:54:38

回答

1

你可以用下面的代码滚动自己的99%。由于需要封装某个集合的成员,它会给您带来两个编译错误,但它确实会让您超过不再值得自动化的地步。

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); 
    } 
} 
} 
+0

我会看看它,谢谢! – TofuBeer 2011-04-04 16:30:04