org.neo4j.kernel.impl.annotations.CompilationManipulator Maven / Gradle / Ivy
/*
* Copyright (c) 2002-2015 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.kernel.impl.annotations;
import java.util.Map;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
abstract class CompilationManipulator
{
static CompilationManipulator load( AnnotationProcessor proc, ProcessingEnvironment processingEnv )
{
for ( Environment env : Environment.values() )
{
CompilationManipulator manipulator = env.load( proc, processingEnv );
if ( manipulator != null ) return manipulator;
}
return null;
}
private enum Environment
{
JAVAC( "com.sun.tools.javac.processing.JavacProcessingEnvironment" )
{
@Override
CompilationManipulator create( AnnotationProcessor proc, ProcessingEnvironment env )
{
return new JavacManipulator( proc, env );
}
};
private final Class> environment;
private Environment( String environment )
{
this.environment = loadClass( environment );
}
CompilationManipulator load( AnnotationProcessor proc, ProcessingEnvironment env )
{
try
{
if ( environment != null && environment.isInstance( env ) && canLoad( env ) )
{
return create( proc, env );
}
}
catch ( Exception e )
{
return null;
}
catch ( LinkageError e )
{
return null;
}
return null;
}
boolean canLoad( @SuppressWarnings( "unused" ) ProcessingEnvironment env )
{
return true;
}
abstract CompilationManipulator create( AnnotationProcessor proc, ProcessingEnvironment env );
private static Class> loadClass( String className )
{
try
{
return Class.forName( className );
}
catch ( Throwable e )
{
return null;
}
}
}
abstract boolean updateAnnotationValue( Element annotated, AnnotationMirror annotation, String key, String value );
abstract boolean addAnnotation( Element target, String annotationType, Map parameters );
@SuppressWarnings( "restriction" )
private static class JavacManipulator extends CompilationManipulator
{
private final AnnotationProcessor proc;
private final com.sun.source.util.Trees trees;
private final com.sun.tools.javac.tree.TreeMaker maker;
private final com.sun.tools.javac.model.JavacElements elements;
JavacManipulator( AnnotationProcessor proc, ProcessingEnvironment env )
{
com.sun.tools.javac.util.Context context = ( (com.sun.tools.javac.processing.JavacProcessingEnvironment) env )
.getContext();
this.proc = proc;
this.trees = com.sun.source.util.Trees.instance( env );
this.maker = com.sun.tools.javac.tree.TreeMaker.instance( context );
this.elements = com.sun.tools.javac.model.JavacElements.instance( context );
}
@Override
boolean updateAnnotationValue( Element annotated, AnnotationMirror annotation, String key, String value )
{
com.sun.source.tree.Tree leaf = trees.getTree( annotated, annotation );
if ( leaf instanceof com.sun.tools.javac.tree.JCTree.JCAnnotation )
{
com.sun.tools.javac.tree.JCTree.JCAnnotation annot = (com.sun.tools.javac.tree.JCTree.JCAnnotation) leaf;
for ( com.sun.tools.javac.tree.JCTree.JCExpression expr : annot.args )
{
if ( expr instanceof com.sun.tools.javac.tree.JCTree.JCAssign )
{
com.sun.tools.javac.tree.JCTree.JCAssign assign = (com.sun.tools.javac.tree.JCTree.JCAssign) expr;
if ( assign.lhs instanceof com.sun.tools.javac.tree.JCTree.JCIdent )
{
com.sun.tools.javac.tree.JCTree.JCIdent ident = (com.sun.tools.javac.tree.JCTree.JCIdent) assign.lhs;
if ( ident.name.contentEquals( key ) )
{
assign.rhs = maker.Literal( value );
return true;
}
}
}
}
annot.args = annot.args.append( assignment( key, value ) );
return true;
}
return false;
}
@Override
boolean addAnnotation( Element target, String annotationType, Map parameters )
{
com.sun.source.tree.Tree leaf = trees.getPath( target ).getLeaf();
final com.sun.tools.javac.tree.JCTree.JCModifiers modifiers;
if ( leaf instanceof com.sun.tools.javac.tree.JCTree.JCMethodDecl )
{
com.sun.tools.javac.tree.JCTree.JCMethodDecl method = (com.sun.tools.javac.tree.JCTree.JCMethodDecl) leaf;
modifiers = method.mods != null ? method.mods : ( method.mods = makeModifiers( target, 0 ) );
}
else if ( leaf instanceof com.sun.tools.javac.tree.JCTree.JCClassDecl )
{
com.sun.tools.javac.tree.JCTree.JCClassDecl clazz = (com.sun.tools.javac.tree.JCTree.JCClassDecl) leaf;
modifiers = clazz.mods != null ? clazz.mods : ( clazz.mods = makeModifiers( target, 0 ) );
}
else if ( leaf instanceof com.sun.tools.javac.tree.JCTree.JCVariableDecl )
{
com.sun.tools.javac.tree.JCTree.JCVariableDecl param = (com.sun.tools.javac.tree.JCTree.JCVariableDecl) leaf;
modifiers = param.mods != null ? param.mods : ( param.mods = makeModifiers( target, 0 ) );
}
else
{
return false;
}
for ( com.sun.tools.javac.tree.JCTree.JCAnnotation annotation : modifiers.annotations )
{
if ( annotation.annotationType instanceof com.sun.tools.javac.tree.JCTree.JCIdent )
{
com.sun.tools.javac.tree.JCTree.JCIdent ident = (com.sun.tools.javac.tree.JCTree.JCIdent) annotation.annotationType;
if ( ident.getName().contentEquals( annotationType ) ) return false;
}
}
modifiers.annotations = modifiers.annotations.prepend( maker.Annotation( typeName( annotationType ),
makeParams( parameters ) ) );
return true;
}
private com.sun.tools.javac.tree.JCTree.JCExpression typeName( String typeName )
{
String[] parts = typeName.split( "\\.", -1 );
com.sun.tools.javac.tree.JCTree.JCExpression exp = maker.Ident( elements.getName( parts[0] ) );
for ( int i = 1; i < parts.length; i++ )
exp = maker.Select( exp, elements.getName( parts[i] ) );
return exp;
}
private com.sun.tools.javac.tree.JCTree.JCModifiers makeModifiers( Element target, long flags )
{
proc.warn( target, "No modifiers, creating default" );
return maker.Modifiers( flags,
com.sun.tools.javac.util.List.nil() );
}
private com.sun.tools.javac.util.List makeParams(
Map parameters )
{
com.sun.tools.javac.util.List result = com.sun.tools.javac.util.List
.nil();
for ( Map.Entry entry : parameters.entrySet() )
{
result = result.prepend( assignment( entry.getKey(), entry.getValue() ) );
}
return result;
}
private com.sun.tools.javac.tree.JCTree.JCAssign assignment( String key, Object value )
{
return maker.Assign( maker.Ident( elements.getName( key ) ), maker.Literal( value ) );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy