2013-06-27 4 views
0

코드를 생성해야하며이 경우에는 suns CodeModel 라이브러리를 사용하여 주석을 생성해야합니다. 주석 치는 Class 객체입니다. 그러나이 클래스는 컴파일 타임에 알려지지 않습니다. 내가 지금 가지고있는 솔루션입니다 : Java CodeModel : 값으로 클래스를 사용하는 주석 - 클래스 경로에없는 클래스

JAnnotationUse oneToMany = field.annotate(OneToMany.class) 
    .param("targetEntity", Class.forName(className); 

그러나 이것은 분명히에 따라 클래스가 클래스 경로에 있어야합니다. 나는 사용자가 그런 문제를 다루지 않아도되도록하고 싶다.

물론 다른 옵션은 자바 소스 코드 파일을 생성하고 나중에 순수한 문자열로 조작하는 것이지만 매우 엉망입니다.

일반 문자열 className + ".class"대신 CodeModel을 사용할 수 있습니까?

+0

왜 이미 인수에 사용하는'Class.forName() '이 아닌가요? – fge

+0

왜냐하면 클래스를로드해야하기 때문입니다. 그리고 모든 클래스가 될 수 있기 때문에 클래스 경로에 있다는 보장이 없습니다. 사용자가 클래스 경로에 병을 추가하는 방법을 이해할 필요가 없어야한다는 것을 의미하는 사용자 친화적이어야합니다. –

답변

0

Ok. 여기 내 해결책. javaassist를 사용하여 런타임에 클래스 및 해당 Class 객체를 생성합니다. 최종 결과는 자바 소스 코드 파일에 일반 텍스트로

@OneToMany(targetEntity = com.foo.Bar.class) 

될 것이기 때문에,이 생성 된 "더미 클래스"실제로 참조 된 실제 실제 클래스와 일치하지 않는 것을 중요하지 않습니다.

그래서 Guillaume이 표시된대로 주석 만들기를 조정하고 ClassNotfoundExeption을 잡습니다.

JAnnotationUse oneToMany = field.annotate(OneToMany.class); 
//...snipped... 
    try { 
     oneToMany.param("targetEntity", Class.forName(jpaProperty.getTargetEntity())); 
    } catch (ClassNotFoundException ex) { 
     try { 
      Class targetEntityClass = generateDummyClass(jpaProperty.getTargetEntity()); 
      oneToMany.param("targetEntity", targetEntityClass); 
     } catch (CannotCompileException compileEx) { 
      throw ex; 
     } 
    } 
} 

방법 generateDummyClass javaassist 사용하여 런타임에 클래스의 객체를 생성 : 예외 처리기에서 우리는 클래스 객체 생성 javaassist를 사용하는 generateDummyClass 메서드를 호출

private Class<?> generateDummyClass(String fullQualifedClassName) 
     throws IOException, CannotCompileException { 

    ClassPool pool = ClassPool.getDefault(); 
    pool.insertClassPath(new ClassClassPath(this.getClass())); 
    CtClass ctClass = pool.makeClass(fullQualifedClassName); 
    Class<?> clazz = ctClass.toClass(); 
    return clazz; 
} 

을 우리는 자바 소스를 얻을 수 코드 파일 :

@OneToMany(targetEntity = org.foo.Bar.class) 
private Set<Bar> bars = new HashSet<Bar>(); 
0

당신은 경우를 처리 할 수있는 끼 클래스 패스의 클래스 그것을하지 ClassNotFoundException :

try { 
JAnnotationUse oneToMany = field.annotate(OneToMany.class) 
    .param("targetEntity", Class.forName(className); 
} catch (ClassNotFoundException e) { 
// handle the exception 
} 

당신은 예외가 정말로에 따라, 당신이 달성하려고하는지에 따라 처리 부분 오류를 기록하거나 다른 anotation을 추가하거나 예외를 던지기를 원할 수도 있습니다. ...

관련 문제