2010-11-17 50 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