/************************************************************************* * Copyright 2009-2013 Eucalyptus Systems, Inc. * * This program 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; version 3 of the License. * * 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 http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package edu.ucsb.eucalyptus.msgs; import java.lang.reflect.Modifier; import java.util.UUID; import org.codehaus.groovy.ast.ASTNode; import org.codehaus.groovy.ast.AnnotationNode; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.FieldNode; import org.codehaus.groovy.ast.PackageNode; import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.control.CompilePhase; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.transform.ASTTransformation; import org.codehaus.groovy.transform.GroovyASTTransformation; import com.google.common.base.Charsets; import groovyjarjarasm.asm.Opcodes; /** * ASTTransformation that adds a UUID field to classes in the source unit. */ @GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION) public class GroovyAddClassUUIDASTTransformation implements ASTTransformation { public void visit( final ASTNode[] nodes, final SourceUnit sourceUnit) { if ( null == nodes || nodes.length < 2 ) return; if (!(nodes[0] instanceof AnnotationNode)) return; if (!(nodes[1] instanceof PackageNode)) return; for ( ClassNode cNode : sourceUnit.getAST().getClasses() ) { if ( !Modifier.isInterface( cNode.getModifiers( ) ) && cNode.getDeclaredField( "$EUCA_CLASS_UUID" ) == null ) { final FieldNode field = new FieldNode( "$EUCA_CLASS_UUID", Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC, new ClassNode(String.class), new ClassNode(cNode.getClass()), new ConstantExpression( UUID.nameUUIDFromBytes( cNode.getName().getBytes( Charsets.UTF_8 ) ).toString( ) ) ); cNode.addField( field ); // Added so Groovy thinks it has already added the "__timeStamp__239_neverHappen$TIMESTAMP" field and skips it final FieldNode timeTagField = new FieldNode( "__timeStamp", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, new ClassNode(Long.class), new ClassNode(cNode.getClass()), new ConstantExpression( 0 ) ); cNode.addField( timeTagField ); } } } }