我正在寻找一种在构建过程中从Java类生成aspectJ方面的方法。 目标是生成一个类型间声明方面,其中包含java类的每个属性的String常量。
Java类:
public class CarDTO {
private String vendor;
private String name;
public String getVendor() {}
public String getName() {}
[..]
}
这是应该生成的方面:
aspect CarAspect
{
public static final String CarDTO.VENDOR = "vendor";
public static final String CarDTO.NAME = "name";
}
是否有任何obne知道maven等工具或插件可以实现此行为?
由于
马丁
答案 0 :(得分:1)
您可以使用CodeSmith Generator生成此代码。如果您在Visual Studio内使用JScript(Microsoft),则可以使用我们的GenerateOnBuild or MSBuild(see this document aswell)支持。否则,您可以在构建过程中对CodeSmith Generator可执行文件进行shell操作,并使其生成代码。
需要构建自定义模板来解析文件并生成代码。开箱即用,我们支持Parsing Visual Basic or CSharp Code Files并生成Visual Basic或CSharp(这对您没有帮助,但它向您显示已完成并受支持)。这是一些documentation on creating a custom template。
另外,我知道你可以选择compiled jar file and convert it to a .NET assembly。从这里,您可以在模板中使用reflection并生成Java代码。
这可能不是最佳选择,因为您没有Eclipse集成(取决于您的编辑器,但它是一种可以轻松解决此问题的替代解决方案。您也可以使用JScript,CSharp或Visual Basic编写模板) )
由于 -Blake Niemyjski(CodeSmith员工)
答案 1 :(得分:1)
也许您可以尝试注释处理。见apt:
http://download.oracle.com/javase/1.5.0/docs/guide/apt/GettingStarted.html
Eclipse和AspectJ识别完整和增量构建中的注释处理。
答案 2 :(得分:1)
那么, 最后我得到了一个解决方案,但仍然陷入困境。 apt的暗示是成功的。
我设法创建了一个AnnotationProcessor,它生成一个方面作为String。这就是问题所在。创建一个新的File对象并将String粘贴到其中为每个带注释的类创建方面文件是不是很糟糕? 这是我目前可以成像的唯一方式。
感谢
马丁
<强>解决方案:强>
我创建了一个AnnotationProcessor(JDK1.6)来创建我的方面。 generateAspect方法在每个方面的默认源输出文件夹中创建一个文件。
@SupportedAnnotationTypes( { "my.own.annotation.GenerateDTOConstants" } )
@SupportedSourceVersion( SourceVersion.RELEASE_6 )
public class DTOConstantAnnotationProcessor extends AbstractProcessor {
private static final Logger LOG = LoggerFactory
.getLogger( DTOConstantAnnotationProcessor.class );
private static final String ASPECT_POSTFIX = ".aj";
@Override
public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv ) {
DTOConstantElementVisitor visitor = new DTOConstantElementVisitor();
for( TypeElement element : annotations ) {
Set<? extends Element> annotatedClasses = roundEnv.getElementsAnnotatedWith( element );
for( Element dto : annotatedClasses ) {
generateAspect( visitor, dto );
}
}
return true;
}
/**
* @param visitor
* @param dto
*/
private void generateAspect( DTOConstantElementVisitor visitor, Element dto ) {
dto.accept( visitor, null );
LOG.info( "Generating aspect for " + dto.getSimpleName() );
Filer filer = this.processingEnv.getFiler();
try {
String fileName = visitor.getFileName() + ASPECT_POSTFIX;
String pkg = visitor.getPkg();
FileObject aspectFile = filer.createResource( StandardLocation.SOURCE_OUTPUT, pkg,
fileName );
Writer writer = aspectFile.openWriter();
LOG.info( "writing aspect content into file" );
writer.write( visitor.getFileContent() );
writer.close();
LOG.info( "Aspect generated for " + visitor.getFileName() );
}
catch( IOException e ) {
e.printStackTrace();
throw new java.lang.RuntimeException( e );
}
}
}
这里是我使用的访问者(只是一个片段):
public class DTOConstantElementVisitor extends AbstractElementVisitor6<Void, String> {
private static final String FIELD_PREFIX = "public static final String ";
private String fileName = null;
private String clazzName;
private String pkg;
private StringBuffer fileContentBuff;
@Override
public Void visitPackage( PackageElement e, String p ) {
System.out.println( "visitPackage" + e );
return null;
}
@Override
public Void visitType( TypeElement e, String p ) {
System.out.println( "visitTypeElement" + e );
try {
Class<?> clazz = Class.forName( e.getQualifiedName().toString() );
this.clazzName = clazz.getSimpleName();
createFileName( clazz );
this.pkg = clazz.getPackage().getName();
this.fileContentBuff = new StringBuffer();
fileContentBuff.append( "package " + this.pkg + ";\n" );
fileContentBuff.append( "public aspect " + this.fileName + " {\n" );
for( Field field : clazz.getDeclaredFields() ) {
if( Modifier.isPrivate( field.getModifiers() ) ) {
String fieldName = field.getName();
if( shouldGenerateField( fieldName ) ) {
fileContentBuff.append( FIELD_PREFIX + clazzName + "."
+ fieldName.toUpperCase() + " = \"" + fieldName + "\";\n" );
}
}
}
fileContentBuff.append( "}\n" );
System.out.println( fileContentBuff.toString() );
}
catch( ClassNotFoundException e1 ) {
throw new java.lang.RuntimeException( e1 );
}
return null;
}
private boolean shouldGenerateField( String fieldName ) {
if( "serialVersionUID".equals( fieldName ) ) {
return false;
}
return true;
}
private void createFileName( Class clazz ) {
this.fileName = clazzName + "Aspect";
}
}
另外,您必须在
中创建配置文件META-INF/services
称为
javax.annotation.processing.Processor
包含包和AnnotationProcessor的名称
my.package.annotation.processor.DTOConstantAnnotationProcessor
最后,maven构建过程中的include:
<build>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.0.0</version>
<executions>
<execution>
<id>aspectprocessing</id>
<phase>compile</phase>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
</build>
单击目标使用
mvn processor:process
多数人=)
答案 3 :(得分:0)
AspectJ Version 1.8.2现在支持Annotation Processing。您可以使用此功能在构建过程中生成ApspectJ文件,由某些注释触发。
请参阅此博客文章以获取示例: http://andrewclement.blogspot.de/2014/08/annotation-processing-in-ajdt.html