in heartbeat, tasktrackername had illegal chars

import java.io.*;
import java.util.*;
import java.lang.management.ManagementFactory;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.net.InetAddress;
import java.lang.ClassLoader;
import org.apache.hadoop.io.DataInputBuffer;
import org.apache.hadoop.mapred.TaskStatus;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.Progressable;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.util.DataChecksum;
import java.net.Socket;

import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;
import org.apache.hadoop.hdfs.security.token.block.BlockTokenIdentifier;

import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.hdfs.DFSClient;

import org.apache.hadoop.mapred.TaskTrackerStatus;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.hadoop.conf.Configuration;

/**
 *
 * @author Alejandro
 */

aspect AlojaAspect {

	private static final Log LOG = LogFactory.getLog(AlojaAspect.class);

	/*
	TYPES
	######################################################################################################################################
	######################################################################################################################################
	*/

    public static class Events {

        public static final int JobTracker = 11111;
        public static final int TaskTracker = 11112;
        public static final int NameNode = 11113;
        public static final int SecondaryNameNode = 11114;
        public static final int DataNode = 11115;
        public static final int Task = 11116;
//        public static final int MapTask = 11117;
//        public static final int ReduceTask = 11118;
        public static final int MapOutputBuffer = 33333;
        public static final int MapTaskOutputSize = 44444;
    }

    public static class Values {

       	// Generic
		public static final int End = 0;
        public static final int Start = 1;

        // Events.TaskTracker
		public static final int RunMapper = 8;
        public static final int RunReducer = 9;
        public static final int ReducerCopyPhase = 10;
        public static final int ReducerSortPhase = 11;
        public static final int ReducerReducePhase = 12;

		// Events.JobTracker
		public static final int HeartBeat = 13;

		// Events.MapOutputBuffer
        public static final int Flush = 1;
        public static final int SortAndSpill = 2;
        public static final int Sort = 3;
        public static final int CreateSpillIndexFile = 5;
        //public static final int TotalIndexCacheMemory = 6;
        public static final int SpillRecordDumped = 7;
        public static final int Combine = 4;
    }

	/*
	FUNCTIONS
	######################################################################################################################################
	######################################################################################################################################
	*/

	private static long getPID() {
		String name = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
		return Long.parseLong(name.split("@")[0]);
	}

	private void generateEvent(Integer key, Integer value) {
		//2:cpu:app:task:thread:time:type:value
		try{
			String hostname = InetAddress.getLocalHost().getHostName();
			long pid = getPID();
			LOG.info(hostname+","+pid+",2:"+hostname+":2:"+pid+":1:"+System.currentTimeMillis()+":"+key+":"+value);
		}
		catch (Exception e) {
			LOG.error(e, e);

		}
	}

	private void generateEvent(Integer key, String value) {
		//2:cpu:app:task:thread:time:type:value
		try{
			String hostname = InetAddress.getLocalHost().getHostName();
			long pid = getPID();
			LOG.info(hostname+","+pid+",2:"+hostname+":2:"+pid+":1:"+System.currentTimeMillis()+":"+key+":"+value);
		}
		catch (Exception e) {
			LOG.error(e, e);

		}
	}

	/*private void generateEVent(Integer key[], Integer value) {

		StringBuffer output = new StringBuffer();

		output.append()

	}*/

	private void instrumentation(String event, String when) {

		instrumentation(event, when, "");

	}
	private void instrumentation(String event, String when, String additional) {
		try {
			//Add hostname
			String log = InetAddress.getLocalHost().getHostName();
			//Add PID
			log += "," + getPID();
			//Specify event
			log += "," + when + "," + event;
			//Specify event
			log += additional;
			//LOG.info(log);
			//writeLog(logFile,log);

		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

	/*
	POINTCUTS
	######################################################################################################################################
	######################################################################################################################################
	*/

	//RegisterDataNode Pointcut

	pointcut startDataNode(): execution(* org.apache.hadoop.hdfs.server.datanode.DataNode.startDataNode(..));

	//RegisterNameNode Pointcut

	pointcut initializeNameNode():  execution(* org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(..));

	//RegisterSecondaryNamenode Pointcut

	pointcut initializeSecondaryNameNode(): execution(* org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.initialize(..));

	//RegisterTask - CHILD

	//pointcut initializeChild(): call(* org.apache.hadoop.mapred.Child.initMetrics(..)) && withincode(* org.apache.hadoop.mapred.Child.main(..));

	pointcut initializeChild(): execution(* org.apache.hadoop.mapred.Child.main(..));

	//Register JobTracker Pointcut

	pointcut registerJobTracker(): execution(* org.apache.hadoop.mapred.JobTracker.startTracker(..));

	//HEARTBEAT

	pointcut heartbeat(TaskTrackerStatus status,boolean restarted,boolean initialContact,boolean acceptNewTasks,short responseId): execution(* org.apache.hadoop.mapred.JobTracker.heartbeat(..)) && args(status, restarted, initialContact, acceptNewTasks,responseId);

	/*
		###########################################################################
		############################Task###########################################
		###########################################################################
	*/

	pointcut outputSize(): call (* *.getLen(..)) && withincode(* org.apache.hadoop.mapred.Task.calculateOutputSize());

	/*
		###########################################################################
		############################MAPPER#########################################
		###########################################################################
	*/

	//pointcut maptask(): execution(* org.apache.hadoop.mapred.MapTask.run(..));
	pointcut mapper(): call(* org.apache.hadoop.mapred.MapTask.runNewMapper(..)) && withincode(* org.apache.hadoop.mapred.MapTask.run(..));

	//  ############################SORT AND SPILL#################################

	//Start-End
	pointcut taskSortAndSpill(): execution(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	pointcut flush(): execution(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.flush());

	//Spill File Size
	pointcut sortAndSpillSpillFile(int numSpills, long size) : call (* *.getSpillFileForWrite(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(numSpills, size);

	//SpillIndex File Size
	pointcut sortAndSpillSpillIndexFile(int numSpills, long partitions) : call (* *.getSpillIndexFileForWrite(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(numSpills, partitions);

	//Sort
	pointcut sortAndSpillSort(int kvstart, int endPosition, Object reporter): call(* *.sort(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(..,kvstart,endPosition,reporter);

	//Init Writer
	//pointcut sortAndSpillInitWriter() : call (org.apache.hadoop.mapred.IFile.Writer.new(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	//Close Writer
	//pointcut sortAndSpillCloseWriter() : call (void org.apache.hadoop.mapred.IFile.Writer.close(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	//Write key-value
	pointcut sortAndSpillWrite(DataInputBuffer key, DataInputBuffer value): call (* *.append(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(key,value);

	//Combiner
	pointcut sortAndSpillCombiner(): call(* *.combine(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	//Spill Index File
	pointcut sortAndSpillSpillIndexWrite(): call(* *.writeToFile(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	/*
		###########################################################################
		############################REDUCER########################################
		###########################################################################
	*/

	//REDUCETASK RUN
	pointcut reducer(): execution(* org.apache.hadoop.mapred.ReduceTask.run(..));
	pointcut initCodec(): call(* *.initCodec(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..));
	pointcut setPhase(TaskStatus.Phase phase): call(* *.setPhase(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..)) && args(phase);

	//pointcut endCopy(): call(* *.setPhase(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..));
	//pointcut endSort(): call(* *.getMapOutputKeyClass(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..));

	/*
		###########################################################################
		############################NETWORK########################################
		###########################################################################
	*/

	pointcut defaultBlockSize(): call(* org.apache.hadoop.hdfs.DFSClient.getDefaultBlockSize());
	//pointcut blockSize(): call(* org.apache.hadoop.hdfs.DFSClient.getBlockSize(..));
	pointcut createDFSFile(String src,FsPermission permission,boolean overwrite,boolean createParent,short replication,long blockSize,Progressable progress, int buffersize): execution (* org.apache.hadoop.hdfs.DFSClient.create(..)) && args(src,permission,overwrite,createParent,replication,blockSize,progress,buffersize);
	pointcut runDataStreamer(): execution (* org.apache.hadoop.hdfs.DFSClient.DFSOutputStream.DataStreamer.run());
	//pointcut readEntireBufferFromDataNode(byte buf[],int off,int len): execution(* org.apache.hadoop.hdfs.DFSClient.DFSInputStream.read(..)) && args(buf[],off,len);
	//pointcut readFromDataNode(): call (* org.apache.hadoop.hdfs.DFSClient.DFSInputStream.blockSeekTo(..)) && withincode(* org.apache.hadoop.hdfs.DFSClient.DFSInputStream.read(..));
	pointcut newBlockReader(Socket sock, String file, long blockId, Token<BlockTokenIdentifier> accessToken, long genStamp, long startOffset, long len, int bufferSize, boolean verifyChecksum, String clientName): execution (* org.apache.hadoop.hdfs.DFSClient.BlockReader.newBlockReader(..)) && args(sock,file,blockId,accessToken,genStamp,startOffset,len,bufferSize,verifyChecksum,clientName);

	/*
	Advices
	######################################################################################################################################
	######################################################################################################################################
	*/

	// RegiterJobTracker

	after() : registerJobTracker(){
		generateEvent(Events.JobTracker, Values.Start);

	}

	//RegisterTaskTracker ?

	//RegisterNameNode

	after() : initializeNameNode(){
		generateEvent(Events.NameNode, Values.Start);
	}

	//RegisterDataNode

	after() : startDataNode(){
		generateEvent(Events.DataNode, Values.Start);
	}

	//RegisterSecondaryNamenode

	after() : initializeSecondaryNameNode(){
		generateEvent(Events.SecondaryNameNode, Values.Start);
	}

	//HEARTBEAT
	after(TaskTrackerStatus status,boolean restarted,boolean initialContact,boolean acceptNewTasks,short responseId) : heartbeat(status, restarted, initialContact, acceptNewTasks,responseId){
		// SAMPLE trackername: tracker_vagrant-99-01:localhost/127.0.0.1:38149
		generateEvent(Events.JobTracker, status.getTrackerName().replace(':','-').replace('/','_'));
	}

	/*
		###########################################################################
		############################Task###########################################
		###########################################################################
	*/

	//RegisterTask CHILD
	after() : initializeChild() { //We need the  PID of this task to be registered
		generateEvent(Events.Task, Values.Start);
	}

/*	after() returning(long size) : outputSize() {
		String s = "Task-outputSize";
		instrumentation(s,"after",", size: " + Long.toString(size));
	}

	/*
		###########################################################################
		############################Mapper#########################################
		###########################################################################
	*/

	/*before() : maptask(){
		generateEvent(Events.MapTask, Values.Start);
	}*/

	before() : mapper(){
		generateEvent(Events.TaskTracker, Values.RunMapper);
	}

	after() : mapper(){
		generateEvent(Events.TaskTracker, Values.End);
	}

	//  ############################SORT AND SPILL#################################

	before() : taskSortAndSpill(){
		generateEvent(Events.MapOutputBuffer, Values.SortAndSpill);
	}

	after() : taskSortAndSpill(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	//flush

	before() : flush(){
		generateEvent(Events.MapOutputBuffer, Values.Flush);
	}

	after() : flush(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	// Spill File Size

	after(int numSpills, long size) returning : sortAndSpillSpillFile(numSpills, size){
		String s = "sortAndSpillSpillFile";
		instrumentation(s,"after",", numSpills: " +Integer.toString(numSpills) + ";size: " + Long.toString((size*numSpills) + size));
	}

	// SpillIndex File Size

	after(int numSpills, long partitions) returning : sortAndSpillSpillIndexFile(numSpills, partitions){
		String s = "sortAndSpillSpillIndexFile";
		instrumentation(s,"after","," + Long.toString(numSpills * partitions));
	}

/*
	before(int length) : kvbufferState(length){

		String s = "kvbufferState";
		File logFile = getFile();
		instrumentation(logFile,s,"before");
		writeLog(logFile,Integer.toString(length));
	}

*/

	before(int kvstart, int endPosition, Object reporter) : sortAndSpillSort(kvstart,endPosition,reporter){
		generateEvent(Events.MapOutputBuffer, Values.Sort);
		//instrumentation(s,"before","," + Integer.toString(endPosition - kvstart));
	}
	after(int kvstart, int endPosition, Object reporter) returning : sortAndSpillSort(kvstart,endPosition,reporter){
		generateEvent(Events.MapOutputBuffer, Values.End);
		//instrumentation(s,"after","," + Integer.toString(endPosition - kvstart));
	}

	// Init writer
/*	after() returning : sortAndSpillInitWriter(){
		String s = "sortAndSpillInitWriter";
		instrumentation(s,"after");
	}

	// Close writer
	after() returning : sortAndSpillCloseWriter(){
		String s = "sortAndSpillCloseWriter";
		instrumentation(s,"after");
	}
*/

	after(DataInputBuffer key, DataInputBuffer value) returning : sortAndSpillWrite(key,value){
		generateEvent(Events.MapOutputBuffer, Values.SpillRecordDumped);
	}

	before() : sortAndSpillCombiner(){
		generateEvent(Events.MapOutputBuffer, Values.Combine);
	}

	after() returning : sortAndSpillCombiner(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	before() : sortAndSpillSpillIndexWrite(){
		generateEvent(Events.MapOutputBuffer, Values.CreateSpillIndexFile);
	}

	after() returning : sortAndSpillSpillIndexWrite(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	/*
		###########################################################################
		############################REDUCER########################################
		###########################################################################
	*/

/*	before() : reducer(){
		String s = "Reducer";
		instrumentation(s,"before");
	}
*/

	before() : initCodec() {
		generateEvent(Events.TaskTracker, Values.RunReducer);
	}

	after() returning : initCodec() {
		generateEvent(Events.TaskTracker, Values.ReducerCopyPhase);
	}

	before(TaskStatus.Phase phase) : setPhase(phase) { //END OF A PHASE (SORT OR COPY)
			generateEvent(Events.TaskTracker, Values.End);
	}

	after(TaskStatus.Phase phase) returning: setPhase(phase) {
		if (phase == TaskStatus.Phase.SORT) {
			generateEvent(Events.TaskTracker, Values.ReducerSortPhase);
		}
		else if (phase == TaskStatus.Phase.REDUCE) {
			generateEvent(Events.TaskTracker, Values.ReducerReducePhase);
		}
	}

	after() : reducer(){ //END OF REDUCE PHASE
			generateEvent(Events.TaskTracker, Values.End);	}

	/*
		###########################################################################
		############################NETWORK########################################
		###########################################################################
	*/

	after() returning(long blockSize) : defaultBlockSize() {
		String s = "Network-defaultBlockSize";
		instrumentation(s,"after",", size: " + Long.toString(blockSize));
	}
	// after() returning(long blockSize) : blockSize() {
	// 	String s = "Network-blockSize";
	// 	File logFile = getFile();
	// 	instrumentation(logFile,s,"after");
	// 	String log = ", size: " + Long.toString(blockSize);
	// 	writeLog(logFile,log);
	// }

	after(String src,FsPermission permission,boolean overwrite, boolean createParent,short replication,long blockSize,Progressable progress, int buffersize): createDFSFile(src,permission,overwrite,createParent,replication,blockSize,progress,buffersize) {
		String s = "Network-CreateDFSFile";

		//MODIFIED!!!!!!-----!!!!!!!!!!!
		instrumentation(s,"after",", path: " + src + ";permission: " + permission.toString() + ";overwrite: " + String.valueOf(overwrite) + ";createParent: " + String.valueOf(createParent) + ";replication: " + Short.toString(replication) + ";blockSize: " + Long.toString(blockSize) + ";buffersize: " + Integer.toString(buffersize));
	}
	before(): runDataStreamer() {
		String s = "DataStreamer";
		instrumentation(s,"after");
	}

	// before(byte buf[],int off, int len) : readEntireBufferFromDataNode(buf[],off,len){
	// 	String s = "Network-ReadEntireBuffer";
	// 	instrumentation(s,"after",", bufferLength: " + Integer.toString(len));
	// }

	// after() returning(DatanodeInfo datanode) : readFromDataNode(){
	// 	String s = "Network-fromDataNode";
	// 	instrumentation(s,"after", ", from : " + datanode.getHostName());
	// }

	after(Socket sock, String file, long blockId, Token<BlockTokenIdentifier> accessToken, long genStamp, long startOffset, long len, int bufferSize, boolean verifyChecksum, String clientName) : newBlockReader(sock,file,blockId,accessToken,genStamp,startOffset,len,bufferSize,verifyChecksum,clientName) {
		String s = "Network-NewBlockReader";
		String extra = ", DataNode: " + sock.getInetAddress().getCanonicalHostName();
		extra += ";file: " + file;
		//extra += ", length: " + Long.toString(len) + "B";
		extra += ";" + Long.toString(len);
		extra += ";blockId: " + Long.toString(blockId);
		extra += ";startOffset: " + Long.toString(startOffset);
		instrumentation(s,"after",extra);
	}
}

import java.io.*;
import java.util.*;
import java.lang.management.ManagementFactory;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.net.InetAddress;
import java.lang.ClassLoader;
import org.apache.hadoop.io.DataInputBuffer;
import org.apache.hadoop.mapred.TaskStatus;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.Progressable;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.util.DataChecksum;
import java.net.Socket;

import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenIdentifier;
import org.apache.hadoop.hdfs.security.token.block.BlockTokenIdentifier;

import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.hdfs.DFSClient;

import org.apache.hadoop.mapred.TaskTrackerStatus;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.hadoop.conf.Configuration;

/**
 *
 * @author Alejandro
 */

aspect AlojaAspect {

	private static final Log LOG = LogFactory.getLog(AlojaAspect.class);

	/*
	TYPES
	######################################################################################################################################
	######################################################################################################################################
	*/

    public static class Events {

        public static final int JobTracker = 11111;
        public static final int TaskTracker = 11112;
        public static final int NameNode = 11113;
        public static final int SecondaryNameNode = 11114;
        public static final int DataNode = 11115;
        public static final int Task = 11116;
//        public static final int MapTask = 11117;
//        public static final int ReduceTask = 11118;
        public static final int MapOutputBuffer = 33333;
        public static final int MapTaskOutputSize = 44444;
    }

    public static class Values {

       	// Generic
		public static final int End = 0;
        public static final int Start = 1;

        // Events.TaskTracker
		public static final int RunMapper = 8;
        public static final int RunReducer = 9;
        public static final int ReducerCopyPhase = 10;
        public static final int ReducerSortPhase = 11;
        public static final int ReducerReducePhase = 12;

		// Events.JobTracker
		public static final int HeartBeat = 13;

		// Events.MapOutputBuffer
        public static final int Flush = 1;
        public static final int SortAndSpill = 2;
        public static final int Sort = 3;
        public static final int CreateSpillIndexFile = 5;
        //public static final int TotalIndexCacheMemory = 6;
        public static final int SpillRecordDumped = 7;
        public static final int Combine = 4;
    }

	/*
	FUNCTIONS
	######################################################################################################################################
	######################################################################################################################################
	*/

	private static long getPID() {
		String name = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
		return Long.parseLong(name.split("@")[0]);
	}

	private void generateEvent(Integer key, Integer value) {
		//2:cpu:app:task:thread:time:type:value
		try{
			String hostname = InetAddress.getLocalHost().getHostName();
			long pid = getPID();
			LOG.info(hostname+","+pid+",2:"+hostname+":2:"+pid+":1:"+System.currentTimeMillis()+":"+key+":"+value);
		}
		catch (Exception e) {
			LOG.error(e, e);

		}
	}

	private void generateEvent(Integer key, String value) {
		//2:cpu:app:task:thread:time:type:value
		try{
			String hostname = InetAddress.getLocalHost().getHostName();
			long pid = getPID();
			LOG.info(hostname+","+pid+",2:"+hostname+":2:"+pid+":1:"+System.currentTimeMillis()+":"+key+":"+value);
		}
		catch (Exception e) {
			LOG.error(e, e);

		}
	}

	/*private void generateEVent(Integer key[], Integer value) {

		StringBuffer output = new StringBuffer();

		output.append()

	}*/

	private void instrumentation(String event, String when) {

		instrumentation(event, when, "");

	}
	private void instrumentation(String event, String when, String additional) {
		try {
			//Add hostname
			String log = InetAddress.getLocalHost().getHostName();
			//Add PID
			log += "," + getPID();
			//Specify event
			log += "," + when + "," + event;
			//Specify event
			log += additional;
			//LOG.info(log);
			//writeLog(logFile,log);

		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

	/*
	POINTCUTS
	######################################################################################################################################
	######################################################################################################################################
	*/

	//RegisterDataNode Pointcut

	pointcut startDataNode(): execution(* org.apache.hadoop.hdfs.server.datanode.DataNode.startDataNode(..));

	//RegisterNameNode Pointcut

	pointcut initializeNameNode():  execution(* org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(..));

	//RegisterSecondaryNamenode Pointcut

	pointcut initializeSecondaryNameNode(): execution(* org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.initialize(..));

	//RegisterTask - CHILD

	//pointcut initializeChild(): call(* org.apache.hadoop.mapred.Child.initMetrics(..)) && withincode(* org.apache.hadoop.mapred.Child.main(..));

	pointcut initializeChild(): execution(* org.apache.hadoop.mapred.Child.main(..));

	//Register JobTracker Pointcut

	pointcut registerJobTracker(): execution(* org.apache.hadoop.mapred.JobTracker.startTracker(..));

	//HEARTBEAT

	pointcut heartbeat(TaskTrackerStatus status,boolean restarted,boolean initialContact,boolean acceptNewTasks,short responseId): execution(* org.apache.hadoop.mapred.JobTracker.heartbeat(..)) && args(status, restarted, initialContact, acceptNewTasks,responseId);

	/*
		###########################################################################
		############################Task###########################################
		###########################################################################
	*/

	pointcut outputSize(): call (* *.getLen(..)) && withincode(* org.apache.hadoop.mapred.Task.calculateOutputSize());

	/*
		###########################################################################
		############################MAPPER#########################################
		###########################################################################
	*/

	//pointcut maptask(): execution(* org.apache.hadoop.mapred.MapTask.run(..));
	pointcut mapper(): call(* org.apache.hadoop.mapred.MapTask.runNewMapper(..)) && withincode(* org.apache.hadoop.mapred.MapTask.run(..));

	//  ############################SORT AND SPILL#################################

	//Start-End
	pointcut taskSortAndSpill(): execution(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	pointcut flush(): execution(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.flush());

	//Spill File Size
	pointcut sortAndSpillSpillFile(int numSpills, long size) : call (* *.getSpillFileForWrite(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(numSpills, size);

	//SpillIndex File Size
	pointcut sortAndSpillSpillIndexFile(int numSpills, long partitions) : call (* *.getSpillIndexFileForWrite(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(numSpills, partitions);

	//Sort
	pointcut sortAndSpillSort(int kvstart, int endPosition, Object reporter): call(* *.sort(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(..,kvstart,endPosition,reporter);

	//Init Writer
	//pointcut sortAndSpillInitWriter() : call (org.apache.hadoop.mapred.IFile.Writer.new(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	//Close Writer
	//pointcut sortAndSpillCloseWriter() : call (void org.apache.hadoop.mapred.IFile.Writer.close(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	//Write key-value
	pointcut sortAndSpillWrite(DataInputBuffer key, DataInputBuffer value): call (* *.append(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill()) && args(key,value);

	//Combiner
	pointcut sortAndSpillCombiner(): call(* *.combine(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	//Spill Index File
	pointcut sortAndSpillSpillIndexWrite(): call(* *.writeToFile(..)) && withincode(* org.apache.hadoop.mapred.MapTask.MapOutputBuffer.sortAndSpill());

	/*
		###########################################################################
		############################REDUCER########################################
		###########################################################################
	*/

	//REDUCETASK RUN
	pointcut reducer(): execution(* org.apache.hadoop.mapred.ReduceTask.run(..));
	pointcut initCodec(): call(* *.initCodec(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..));
	pointcut setPhase(TaskStatus.Phase phase): call(* *.setPhase(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..)) && args(phase);

	//pointcut endCopy(): call(* *.setPhase(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..));
	//pointcut endSort(): call(* *.getMapOutputKeyClass(..)) && withincode(* org.apache.hadoop.mapred.ReduceTask.run(..));

	/*
		###########################################################################
		############################NETWORK########################################
		###########################################################################
	*/

	pointcut defaultBlockSize(): call(* org.apache.hadoop.hdfs.DFSClient.getDefaultBlockSize());
	//pointcut blockSize(): call(* org.apache.hadoop.hdfs.DFSClient.getBlockSize(..));
	pointcut createDFSFile(String src,FsPermission permission,boolean overwrite,boolean createParent,short replication,long blockSize,Progressable progress, int buffersize): execution (* org.apache.hadoop.hdfs.DFSClient.create(..)) && args(src,permission,overwrite,createParent,replication,blockSize,progress,buffersize);
	pointcut runDataStreamer(): execution (* org.apache.hadoop.hdfs.DFSClient.DFSOutputStream.DataStreamer.run());
	//pointcut readEntireBufferFromDataNode(byte buf[],int off,int len): execution(* org.apache.hadoop.hdfs.DFSClient.DFSInputStream.read(..)) && args(buf[],off,len);
	//pointcut readFromDataNode(): call (* org.apache.hadoop.hdfs.DFSClient.DFSInputStream.blockSeekTo(..)) && withincode(* org.apache.hadoop.hdfs.DFSClient.DFSInputStream.read(..));
	pointcut newBlockReader(Socket sock, String file, long blockId, Token<BlockTokenIdentifier> accessToken, long genStamp, long startOffset, long len, int bufferSize, boolean verifyChecksum, String clientName): execution (* org.apache.hadoop.hdfs.DFSClient.BlockReader.newBlockReader(..)) && args(sock,file,blockId,accessToken,genStamp,startOffset,len,bufferSize,verifyChecksum,clientName);

	/*
	Advices
	######################################################################################################################################
	######################################################################################################################################
	*/

	// RegiterJobTracker

	after() : registerJobTracker(){
		generateEvent(Events.JobTracker, Values.Start);

	}

	//RegisterTaskTracker ?

	//RegisterNameNode

	after() : initializeNameNode(){
		generateEvent(Events.NameNode, Values.Start);
	}

	//RegisterDataNode

	after() : startDataNode(){
		generateEvent(Events.DataNode, Values.Start);
	}

	//RegisterSecondaryNamenode

	after() : initializeSecondaryNameNode(){
		generateEvent(Events.SecondaryNameNode, Values.Start);
	}

	//HEARTBEAT
	after(TaskTrackerStatus status,boolean restarted,boolean initialContact,boolean acceptNewTasks,short responseId) : heartbeat(status, restarted, initialContact, acceptNewTasks,responseId){
		generateEvent(Events.JobTracker, status.getTrackerName());
	}

	/*
		###########################################################################
		############################Task###########################################
		###########################################################################
	*/

	//RegisterTask CHILD
	after() : initializeChild() { //We need the  PID of this task to be registered
		generateEvent(Events.Task, Values.Start);
	}

/*	after() returning(long size) : outputSize() {
		String s = "Task-outputSize";
		instrumentation(s,"after",", size: " + Long.toString(size));
	}

	/*
		###########################################################################
		############################Mapper#########################################
		###########################################################################
	*/

	/*before() : maptask(){
		generateEvent(Events.MapTask, Values.Start);
	}*/

	before() : mapper(){
		generateEvent(Events.TaskTracker, Values.RunMapper);
	}

	after() : mapper(){
		generateEvent(Events.TaskTracker, Values.End);
	}

	//  ############################SORT AND SPILL#################################

	before() : taskSortAndSpill(){
		generateEvent(Events.MapOutputBuffer, Values.SortAndSpill);
	}

	after() : taskSortAndSpill(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	//flush

	before() : flush(){
		generateEvent(Events.MapOutputBuffer, Values.Flush);
	}

	after() : flush(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	// Spill File Size

	after(int numSpills, long size) returning : sortAndSpillSpillFile(numSpills, size){
		String s = "sortAndSpillSpillFile";
		instrumentation(s,"after",", numSpills: " +Integer.toString(numSpills) + ";size: " + Long.toString((size*numSpills) + size));
	}

	// SpillIndex File Size

	after(int numSpills, long partitions) returning : sortAndSpillSpillIndexFile(numSpills, partitions){
		String s = "sortAndSpillSpillIndexFile";
		instrumentation(s,"after","," + Long.toString(numSpills * partitions));
	}

/*
	before(int length) : kvbufferState(length){

		String s = "kvbufferState";
		File logFile = getFile();
		instrumentation(logFile,s,"before");
		writeLog(logFile,Integer.toString(length));
	}

*/

	before(int kvstart, int endPosition, Object reporter) : sortAndSpillSort(kvstart,endPosition,reporter){
		generateEvent(Events.MapOutputBuffer, Values.Sort);
		//instrumentation(s,"before","," + Integer.toString(endPosition - kvstart));
	}
	after(int kvstart, int endPosition, Object reporter) returning : sortAndSpillSort(kvstart,endPosition,reporter){
		generateEvent(Events.MapOutputBuffer, Values.End);
		//instrumentation(s,"after","," + Integer.toString(endPosition - kvstart));
	}

	// Init writer
/*	after() returning : sortAndSpillInitWriter(){
		String s = "sortAndSpillInitWriter";
		instrumentation(s,"after");
	}

	// Close writer
	after() returning : sortAndSpillCloseWriter(){
		String s = "sortAndSpillCloseWriter";
		instrumentation(s,"after");
	}
*/

	after(DataInputBuffer key, DataInputBuffer value) returning : sortAndSpillWrite(key,value){
		generateEvent(Events.MapOutputBuffer, Values.SpillRecordDumped);
	}

	before() : sortAndSpillCombiner(){
		generateEvent(Events.MapOutputBuffer, Values.Combine);
	}

	after() returning : sortAndSpillCombiner(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	before() : sortAndSpillSpillIndexWrite(){
		generateEvent(Events.MapOutputBuffer, Values.CreateSpillIndexFile);
	}

	after() returning : sortAndSpillSpillIndexWrite(){
		generateEvent(Events.MapOutputBuffer, Values.End);
	}

	/*
		###########################################################################
		############################REDUCER########################################
		###########################################################################
	*/

/*	before() : reducer(){
		String s = "Reducer";
		instrumentation(s,"before");
	}
*/

	before() : initCodec() {
		generateEvent(Events.TaskTracker, Values.RunReducer);
	}

	after() returning : initCodec() {
		generateEvent(Events.TaskTracker, Values.ReducerCopyPhase);
	}

	before(TaskStatus.Phase phase) : setPhase(phase) { //END OF A PHASE (SORT OR COPY)
			generateEvent(Events.TaskTracker, Values.End);
	}

	after(TaskStatus.Phase phase) returning: setPhase(phase) {
		if (phase == TaskStatus.Phase.SORT) {
			generateEvent(Events.TaskTracker, Values.ReducerSortPhase);
		}
		else if (phase == TaskStatus.Phase.REDUCE) {
			generateEvent(Events.TaskTracker, Values.ReducerReducePhase);
		}
	}

	after() : reducer(){ //END OF REDUCE PHASE
			generateEvent(Events.TaskTracker, Values.End);	}

	/*
		###########################################################################
		############################NETWORK########################################
		###########################################################################
	*/

	after() returning(long blockSize) : defaultBlockSize() {
		String s = "Network-defaultBlockSize";
		instrumentation(s,"after",", size: " + Long.toString(blockSize));
	}
	// after() returning(long blockSize) : blockSize() {
	// 	String s = "Network-blockSize";
	// 	File logFile = getFile();
	// 	instrumentation(logFile,s,"after");
	// 	String log = ", size: " + Long.toString(blockSize);
	// 	writeLog(logFile,log);
	// }

	after(String src,FsPermission permission,boolean overwrite, boolean createParent,short replication,long blockSize,Progressable progress, int buffersize): createDFSFile(src,permission,overwrite,createParent,replication,blockSize,progress,buffersize) {
		String s = "Network-CreateDFSFile";

		//MODIFIED!!!!!!-----!!!!!!!!!!!
		instrumentation(s,"after",", path: " + src + ";permission: " + permission.toString() + ";overwrite: " + String.valueOf(overwrite) + ";createParent: " + String.valueOf(createParent) + ";replication: " + Short.toString(replication) + ";blockSize: " + Long.toString(blockSize) + ";buffersize: " + Integer.toString(buffersize));
	}
	before(): runDataStreamer() {
		String s = "DataStreamer";
		instrumentation(s,"after");
	}

	// before(byte buf[],int off, int len) : readEntireBufferFromDataNode(buf[],off,len){
	// 	String s = "Network-ReadEntireBuffer";
	// 	instrumentation(s,"after",", bufferLength: " + Integer.toString(len));
	// }

	// after() returning(DatanodeInfo datanode) : readFromDataNode(){
	// 	String s = "Network-fromDataNode";
	// 	instrumentation(s,"after", ", from : " + datanode.getHostName());
	// }

	after(Socket sock, String file, long blockId, Token<BlockTokenIdentifier> accessToken, long genStamp, long startOffset, long len, int bufferSize, boolean verifyChecksum, String clientName) : newBlockReader(sock,file,blockId,accessToken,genStamp,startOffset,len,bufferSize,verifyChecksum,clientName) {
		String s = "Network-NewBlockReader";
		String extra = ", DataNode: " + sock.getInetAddress().getCanonicalHostName();
		extra += ";file: " + file;
		//extra += ", length: " + Long.toString(len) + "B";
		extra += ";" + Long.toString(len);
		extra += ";blockId: " + Long.toString(blockId);
		extra += ";startOffset: " + Long.toString(startOffset);
		instrumentation(s,"after",extra);
	}
}


Excluded nested classes.

Excluded nested classes.

git-svn-id: 4050ee570c0b454ed3c2eee326cdaf8b6ad603bd@38 e65ff1b4-dc2a-11dd-afbb-e3e17473af86

package org.jsuffixarrays;

/**
 * This aspect logs the memory state at entry and exit from methods
 * declared in inheriting aspects. The aspect is a singleton, so is generally
 * not very useful for multi-threaded applications or whenever more than one instance
 * of a given instrumented class is used.
 */
abstract aspect MemoryLogger issingleton()
{
    /**
     * Declare classes to track memory from.
     */
    abstract pointcut tracedClasses();

    /**
     * Override and remove methods for which logging should not occur.
     */
    pointcut excludedMethods() : !execution(* *(..));

    /**
     * Declare methods to track memory in.
     */
    final pointcut tracedMethods() :
        tracedClasses() && execution(* *(..)) && !excludedMethods();

    /**
     *
     */
    before () : tracedClasses() && tracedMethods()
    {
        update();
    }

    /**
     *
     */
    after () returning : tracedMethods()
    {
        update();
    }

    /**
     * Starting amount of memory from which we will begin measurements.
     *
     * @see #reset()
     */
    private static volatile long startingPoint;

    /*
     *
     */
    private static volatile long maxMemoryUsed;

    /*
     *
     */
    private static void update()
    {
        final long now = getUsedMemory();
        if (maxMemoryUsed < now)
        {
            maxMemoryUsed = now;
        }
    }

    /*
     *
     */
    private static long getUsedMemory()
    {
        final Runtime rt = Runtime.getRuntime();
        return rt.totalMemory() - rt.freeMemory();
    }

    /**
     * Reset memory status, preparing for measurement.
     */
    public static void reset()
    {
        // Try to clean the GC. Will not work for parallel GC, but we did our best.
        for (int i = 0; i < 5; i++)
        {
            System.gc();
        }

        startingPoint = getUsedMemory();
        maxMemoryUsed = 0;
    }

    /**
     * Returns the absolute memory peak recorded so far.
     */
    public static long getMemoryPeak()
    {
        return maxMemoryUsed;
    }

    /**
     * Returns the maximum memory difference from the last time
     * since {@link #reset()} was called. This value may be negative
     * with certain GCs and scenarios.
     */
    public static long getMemoryUsed()
    {
        return maxMemoryUsed - startingPoint;
    }
}

/**
 * Track memory in {@link Skew} algorithm.
 */
aspect SkewMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(Skew);
    @Override
    pointcut excludedMethods(): execution(* leq*(..));
}

/**
 * Track memory in {@link NaiveSort} algorithm.
 */
aspect NaiveSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(NaiveSort);
    @Override
    pointcut excludedMethods(): execution(* compare(..));
}

/**
 * Track memory in {@link DivSufSort} algorithm.
 */
aspect DivSufSortMemLogger extends MemoryLogger
{
    /*
     * 3 private methods using stack are excluded,
     * because they use max. 64 * 4 bytes of extra memory for stack.
     */
    @Override
    pointcut tracedClasses(): within(DivSufSort) && !within(org.jsuffixarrays.DivSufSort..*);
    @Override
    pointcut excludedMethods(): execution(private * *(..)) ;
}

/**
 * Track memory in {@link QSufSort} algorithm.
 */
aspect QSUfSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(QSufSort);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link BPR} algorithm.
 */
aspect BPRMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(BPR);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link DeepShallow} algorithm.
 */
aspect DeepShallowMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(DeepShallow);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link SAIS} algorithm.
 */
aspect SaisMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(SAIS) && !within(org.jsuffixarrays.SAIS..*);

    @Override
    pointcut excludedMethods(): execution(private * *(..))
        && !execution(private * SA_IS(..))
        && !execution(private * induceSA(..));
}

package org.jsuffixarrays;

/**
 * This aspect logs the memory state at entry and exit from methods
 * declared in inheriting aspects. The aspect is a singleton, so is generally
 * not very useful for multi-threaded applications or whenever more than one instance
 * of a given instrumented class is used.
 */
abstract aspect MemoryLogger issingleton()
{
    /**
     * Declare classes to track memory from.
     */
    abstract pointcut tracedClasses();

    /**
     * Override and remove methods for which logging should not occur.
     */
    pointcut excludedMethods() : !execution(* *(..));

    /**
     * Declare methods to track memory in.
     */
    final pointcut tracedMethods() :
        tracedClasses() && execution(* *(..)) && !excludedMethods();

    /**
     *
     */
    before () : tracedClasses() && tracedMethods()
    {
        update();
    }

    /**
     *
     */
    after () returning : tracedMethods()
    {
        update();
    }

    /**
     * Starting amount of memory from which we will begin measurements.
     *
     * @see #reset()
     */
    private static volatile long startingPoint;

    /*
     *
     */
    private static volatile long maxMemoryUsed;

    /*
     *
     */
    private static void update()
    {
        final long now = getUsedMemory();
        if (maxMemoryUsed < now)
        {
            maxMemoryUsed = now;
        }
    }

    /*
     *
     */
    private static long getUsedMemory()
    {
        final Runtime rt = Runtime.getRuntime();
        return rt.totalMemory() - rt.freeMemory();
    }

    /**
     * Reset memory status, preparing for measurement.
     */
    public static void reset()
    {
        // Try to clean the GC. Will not work for parallel GC, but we did our best.
        for (int i = 0; i < 5; i++)
        {
            System.gc();
        }

        startingPoint = getUsedMemory();
        maxMemoryUsed = 0;
    }

    /**
     * Returns the absolute memory peak recorded so far.
     */
    public static long getMemoryPeak()
    {
        return maxMemoryUsed;
    }

    /**
     * Returns the maximum memory difference from the last time
     * since {@link #reset()} was called. This value may be negative
     * with certain GCs and scenarios.
     */
    public static long getMemoryUsed()
    {
        return maxMemoryUsed - startingPoint;
    }
}

/**
 * Track memory in {@link Skew} algorithm.
 */
aspect SkewMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(Skew);
    @Override
    pointcut excludedMethods(): execution(* leq*(..));
}

/**
 * Track memory in {@link NaiveSort} algorithm.
 */
aspect NaiveSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(NaiveSort);
    @Override
    pointcut excludedMethods(): execution(* compare(..));
}

/**
 * Track memory in {@link DivSufSort} algorithm.
 */
aspect DivSufSortMemLogger extends MemoryLogger
{
    /* 3 methods using stack are excluded, because they use max. 64 * 4 bytes of extra memory for stack */
    // TODO: somehow exclude TRBudget class; within(DivSufSort && !DivSufSort.TRBudget) does not work);
    @Override
    pointcut tracedClasses(): within(DivSufSort);
    @Override
    pointcut excludedMethods(): execution(private * *(..)) ;
}

/**
 * Track memory in {@link QSufSort} algorithm.
 */
aspect QSUfSortMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(QSufSort);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link BPR} algorithm.
 */
aspect BPRMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(BPR);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link DeepShallow} algorithm.
 */
aspect DeepShallowMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(DeepShallow);
    @Override
    pointcut excludedMethods(): execution(private * *(..));
}

/**
 * Track memory in {@link SAIS} algorithm.
 */
aspect SaisMemLogger extends MemoryLogger
{
    @Override
    pointcut tracedClasses() : within(SAIS) && !within(org.jsuffixarrays.SAIS..*);

    @Override
    pointcut excludedMethods(): execution(private * *(..))
        && !execution(private * SA_IS(..))
        && !execution(private * induceSA(..));
}


Remove unexpected traces on console output

/*
 *     ParallelJ, framework for parallel computing
 *
 *     Copyright (C) 2010, 2011, 2012 Atos Worldline or third-party contributors as
 *     indicated by the @author tags or express copyright attribution
 *     statements applied by the authors.
 *
 *     This library is free software; you can redistribute it and/or
 *     modify it under the terms of the GNU Lesser General Public
 *     License as published by the Free Software Foundation; either
 *     version 2.1 of the License.
 *
 *     This library 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
 *     Lesser General Public License for more details.
 *
 *     You should have received a copy of the GNU Lesser General Public
 *     License along with this library; if not, write to the Free Software
 *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
package org.parallelj.internal.util.sm.impl;

import javax.xml.bind.annotation.XmlTransient;

import org.aspectj.lang.reflect.MethodSignature;
import org.parallelj.internal.util.sm.StateListener;
import org.parallelj.internal.util.sm.impl.KStateMachine.KVertex;
import org.parallelj.internal.util.sm.impl.KStateMachine.Occurrence;

public privileged aspect KStateMachines {

	/**
	 *
	 */
	public static interface Adapter {

	}

	/**
	 * Inter type declaration in order to link annotated classes and state
	 * machine occurrence.
	 */
	@XmlTransient
	public Occurrence Adapter.occurrence;

	declare parents:
		(@org.parallelj.internal.util.sm.StateMachine *) implements Adapter;

	public static privileged aspect PerMachine pertypewithin(@org.parallelj.internal.util.sm.StateMachine *) {

		KStateMachine machine;

		after() : staticinitialization(@org.parallelj.internal.util.sm.StateMachine *) {
			this.machine = new KStateMachine(thisJoinPoint.getSignature()
					.getDeclaringType());
			//System.out.println(this.machine);
		}

		after(Object self): execution((@org.parallelj.internal.util.sm.StateMachine *).new(..)) && this(self) {
			((Adapter) self).occurrence = this.machine.newOccurrence(self);
		}

		void around(Object self): execution(@org.parallelj.internal.util.sm.Trigger * *(..)) && this(self) {
			Occurrence occurrence = ((Adapter) self).occurrence;
			KVertex previous = occurrence.getCurrent();
			KTrigger trigger = this.machine
					.getTrigger(((MethodSignature) thisJoinPoint.getSignature())
							.getName());
			occurrence.trigger(trigger.trigger(occurrence,
					thisJoinPoint.getArgs()));
			KVertex current = occurrence.getCurrent();
			if (previous != current && current != null) {
				occurrence.getSupport().fireStateChanded(current.value);
			}
		}
	}

	void around(Object machine, StateListener listener): execution(* org.parallelj.internal.util.sm.StateMachines.addStateListener(..)) && args(machine, listener, ..) {
		Occurrence occurrence = ((Adapter) machine).occurrence;
		occurrence.getSupport().addStateListener(listener);
	}

	void around(Object machine, StateListener listener): execution(* org.parallelj.internal.util.sm.StateMachines.removeStateListener(..)) && args(machine, listener, ..) {
		Occurrence occurrence = ((Adapter) machine).occurrence;
		occurrence.getSupport().removeStateListener(listener);
	}

}

/*
 *     ParallelJ, framework for parallel computing
 *
 *     Copyright (C) 2010, 2011, 2012 Atos Worldline or third-party contributors as
 *     indicated by the @author tags or express copyright attribution
 *     statements applied by the authors.
 *
 *     This library is free software; you can redistribute it and/or
 *     modify it under the terms of the GNU Lesser General Public
 *     License as published by the Free Software Foundation; either
 *     version 2.1 of the License.
 *
 *     This library 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
 *     Lesser General Public License for more details.
 *
 *     You should have received a copy of the GNU Lesser General Public
 *     License along with this library; if not, write to the Free Software
 *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
package org.parallelj.internal.util.sm.impl;

import javax.xml.bind.annotation.XmlTransient;

import org.aspectj.lang.reflect.MethodSignature;
import org.parallelj.internal.util.sm.StateListener;
import org.parallelj.internal.util.sm.impl.KStateMachine.KVertex;
import org.parallelj.internal.util.sm.impl.KStateMachine.Occurrence;

public privileged aspect KStateMachines {

	/**
	 *
	 */
	public static interface Adapter {

	}

	/**
	 * Inter type declaration in order to link annotated classes and state
	 * machine occurrence.
	 */
	@XmlTransient
	public Occurrence Adapter.occurrence;

	declare parents:
		(@org.parallelj.internal.util.sm.StateMachine *) implements Adapter;

	public static privileged aspect PerMachine pertypewithin(@org.parallelj.internal.util.sm.StateMachine *) {

		KStateMachine machine;

		after() : staticinitialization(@org.parallelj.internal.util.sm.StateMachine *) {
			this.machine = new KStateMachine(thisJoinPoint.getSignature()
					.getDeclaringType());
			System.out.println(this.machine);
		}

		after(Object self): execution((@org.parallelj.internal.util.sm.StateMachine *).new(..)) && this(self) {
			((Adapter) self).occurrence = this.machine.newOccurrence(self);
		}

		void around(Object self): execution(@org.parallelj.internal.util.sm.Trigger * *(..)) && this(self) {
			Occurrence occurrence = ((Adapter) self).occurrence;
			KVertex previous = occurrence.getCurrent();
			KTrigger trigger = this.machine
					.getTrigger(((MethodSignature) thisJoinPoint.getSignature())
							.getName());
			occurrence.trigger(trigger.trigger(occurrence,
					thisJoinPoint.getArgs()));
			KVertex current = occurrence.getCurrent();
			if (previous != current && current != null) {
				occurrence.getSupport().fireStateChanded(current.value);
			}
		}
	}

	void around(Object machine, StateListener listener): execution(* org.parallelj.internal.util.sm.StateMachines.addStateListener(..)) && args(machine, listener, ..) {
		Occurrence occurrence = ((Adapter) machine).occurrence;
		occurrence.getSupport().addStateListener(listener);
	}

	void around(Object machine, StateListener listener): execution(* org.parallelj.internal.util.sm.StateMachines.removeStateListener(..)) && args(machine, listener, ..) {
		Occurrence occurrence = ((Adapter) machine).occurrence;
		occurrence.getSupport().removeStateListener(listener);
	}

}


refactored StatOverallGraph

refactored StatOverallGraph

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.LinearGradientPaint;

import javax.swing.JPanel;
import javax.swing.JTabbedPane;

import de.erichseifert.gral.data.DataTable;
import de.erichseifert.gral.plots.BarPlot;
import de.erichseifert.gral.plots.PiePlot;
import de.erichseifert.gral.ui.InteractivePanel;
import de.erichseifert.gral.plots.BarPlot.BarRenderer;
import de.erichseifert.gral.plots.PiePlot.PieSliceRenderer;
import de.erichseifert.gral.plots.points.PointRenderer;
import de.erichseifert.gral.util.GraphicsUtils;
import de.erichseifert.gral.util.Insets2D;
import de.erichseifert.gral.util.Location;
import view.GUI;
import view.UIUpdater;

public privileged aspect StatOverallGraph {
    /** Statistics has to be the last feature executed, such that the subfeatures have the correct gui
     * object before statistics can create the tabbed pane
     */
    declare precedence : Statistics, StatOverallGraph, StatOverallTxt;

    private static GUI gui;

    private static final Color COLOR1 = Color.GREEN;

    @SuppressWarnings("unchecked")
    private static DataTable playedTypes = new DataTable(Integer.class, String.class);
    @SuppressWarnings("unchecked")
    private static DataTable mostExpsvGame = new DataTable(Integer.class, Integer.class, String.class);
    @SuppressWarnings("unchecked")
    private static DataTable wonGames = new DataTable(Integer.class, Double.class, String.class);

    after() returning(GUI gui): call(GUI.new(*)) {
        StatOverallGraph.gui = gui;
    }

    after(JTabbedPane tabbedPane):
			execution(public static void StatisticsHelper.StatisticsPaneCreated(JTabbedPane))
			&& args(tabbedPane) {
        JPanel masterPanel = new JPanel();
        JPanel leftPanel = new JPanel();
        JPanel rightPanel = new JPanel();

        masterPanel.setLayout(new GridLayout(1, 2));
        leftPanel.setLayout(new GridLayout(2, 1));
        rightPanel.setLayout(new GridLayout(1, 1));

        masterPanel.add(leftPanel);
        masterPanel.add(rightPanel);

        updateData();
        leftPanel.add(new InteractivePanel(createExpGameBarPlot()));
        leftPanel.add(new InteractivePanel(createWonGamesBarPlot()));
        rightPanel.add(new InteractivePanel(createPlayedTypesPlot()));

        tabbedPane.addTab("Gesamtstatistiken (Grafik)", masterPanel);
    }

    after() : execution(* UIUpdater.run()) {
        updateData();
    }

    private static void updateData() {
        OverallStatistics data = gui.model.getGameData().getOverallStatistics();

        while (playedTypes.getRowCount() > 0) {
            playedTypes.removeLast();
        }
        playedTypes.add(data.getAnzahlRufspiele(), "Rufspiele");
        playedTypes.add(data.getAnzahlSoli(), "Soli");
        playedTypes.add(data.getAnzahlSoliTout(), "Soli Tout");
        playedTypes.add(data.getAnzahlSoliSie(), "Soli Sie");
        playedTypes.add(data.getAnzahlWeiter(), "Weiter");

        while (mostExpsvGame.getRowCount() > 0) {
            mostExpsvGame.removeLast();
        }
        mostExpsvGame.add(1, data.getTeuerstesRufspiel(), "Rufspiel");
        mostExpsvGame.add(2, data.getTeuerstesSolo(), "Solo");
        mostExpsvGame.add(3, data.getTeuerstesSoloTout(), "Solo Tout");
        mostExpsvGame.add(4, data.getTeuerstesSoloSie(), "Solo Sie");

        while (wonGames.getRowCount() > 0) {
            wonGames.removeLast();
        }
        wonGames.add(1, data.getGesamtWinPerc(), "Gesamt");
        wonGames.add(2, data.getRufspieleWinPerc(), "Rufspiele");
        wonGames.add(3, data.getSoliGesamtWinPerc(), "Soli gesamt");
        wonGames.add(4, data.getSoliNormalWinPerc(), "Soli normal");
        wonGames.add(5, data.getSoliToutWinPerc(), "Soli Tout");
        wonGames.add(6, data.getSoliSieWinPerc(), "Soli Sie");
    }

    private static PiePlot createPlayedTypesPlot() {
        PiePlot plot = new PiePlot(playedTypes);

        PointRenderer pointRenderer = plot.getPointRenderer(playedTypes);
        pointRenderer.setValueVisible(true);
        pointRenderer.setValueColumn(1);

        // Format plot
        plot.getTitle().setText("Anzahl gespielter Spieltypen");
        // Change plot size
        plot.setRadius(0.9);
        // Display a legend
        plot.setLegendVisible(true);
        // Add some margin to the plot area
        plot.setInsets(new Insets2D.Double(20.0, 40.0, 40.0, 40.0));

        PieSliceRenderer pieSliceRenderer = (PieSliceRenderer) plot
                .getPointRenderer(playedTypes);

        // Change relative size of inner region
        pieSliceRenderer.setInnerRadius(0.4);
        // Change the width of gaps between segments
        pieSliceRenderer.setGap(0.2);
        // Show labels
        pieSliceRenderer.setValueVisible(true);
        pieSliceRenderer.setValueColor(Color.WHITE);
        pieSliceRenderer.setValueFont(Font.decode(null).deriveFont(Font.BOLD));

        return plot;
    }

    public BarPlot createExpGameBarPlot() {
        // Create new bar plot
        BarPlot plot = new BarPlot(mostExpsvGame);

        // Format plot
        plot.getTitle().setText("Teuerstes Spiel pro Spieltyp");
        plot.setInsets(new Insets2D.Double(40.0, 40.0, 40.0, 40.0));
        plot.setBarWidth(0.075);

        // Format bars
        PointRenderer pointRenderer = plot.getPointRenderer(mostExpsvGame);
        BarRenderer barRenderer = (BarRenderer) pointRenderer;

        barRenderer.setColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] { COLOR1,
                        GraphicsUtils.deriveBrighter(COLOR1) }));
        barRenderer.setBorderStroke(new BasicStroke(3f));
        barRenderer.setBorderColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] {
                        GraphicsUtils.deriveBrighter(COLOR1), COLOR1 }));

        pointRenderer.setValueVisible(true);
        pointRenderer.setValueColumn(2);

        pointRenderer.setValueLocation(Location.CENTER);
        pointRenderer.setValueColor(GraphicsUtils.deriveDarker(COLOR1));
        pointRenderer.setValueFont(Font.decode(null).deriveFont(Font.BOLD));

        return plot;
    }

    public BarPlot createWonGamesBarPlot() {
        // Create new bar plot
        BarPlot plot = new BarPlot(wonGames);

        // Format plot
        plot.getTitle().setText("Gewonnene Spiele pro Spieltyp (in %)");
        plot.setInsets(new Insets2D.Double(40.0, 40.0, 40.0, 40.0));
        plot.setBarWidth(0.075);

        // Format bars
        PointRenderer pointRenderer = plot.getPointRenderer(wonGames);
        BarRenderer barRenderer = (BarRenderer) pointRenderer;

        barRenderer.setColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] { COLOR1,
                        GraphicsUtils.deriveBrighter(COLOR1) }));
        barRenderer.setBorderStroke(new BasicStroke(3f));
        barRenderer.setBorderColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] {
                        GraphicsUtils.deriveBrighter(COLOR1), COLOR1 }));

        pointRenderer.setValueVisible(true);
        pointRenderer.setValueColumn(2);

        pointRenderer.setValueLocation(Location.CENTER);
        pointRenderer.setValueColor(GraphicsUtils.deriveDarker(COLOR1));
        pointRenderer.setValueFont(Font.decode(null).deriveFont(Font.BOLD));

        return plot;
    }
}

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.LinearGradientPaint;

import javax.swing.JPanel;
import javax.swing.JTabbedPane;

import de.erichseifert.gral.data.DataTable;
import de.erichseifert.gral.plots.BarPlot;
import de.erichseifert.gral.plots.PiePlot;
import de.erichseifert.gral.ui.InteractivePanel;
import de.erichseifert.gral.plots.BarPlot.BarRenderer;
import de.erichseifert.gral.plots.PiePlot.PieSliceRenderer;
import de.erichseifert.gral.plots.points.PointRenderer;
import de.erichseifert.gral.util.GraphicsUtils;
import de.erichseifert.gral.util.Insets2D;
import de.erichseifert.gral.util.Location;
import view.GUI;
import view.UIUpdater;

public privileged aspect StatOverallGraph {
    /** Statistics has to be the last feature executed, such that the subfeatures have the correct gui
     * object before statistics can create the tabbed pane
     */
    declare precedence : Statistics, StatOverallGraph, StatOverallTxt;

    private static GUI gui;
    private static JPanel panel = new JPanel();

    private static final Color COLOR1 = Color.GREEN;

    @SuppressWarnings("unchecked")
    private static DataTable playedTypes = new DataTable(Integer.class, String.class);
    @SuppressWarnings("unchecked")
    private static DataTable mostExpsvGame = new DataTable(Integer.class, Integer.class, String.class);
    @SuppressWarnings("unchecked")
    private static DataTable wonGames = new DataTable(Integer.class, Double.class, String.class);

    after() returning(GUI gui): call(GUI.new(*)) {
        StatOverallGraph.gui = gui;
    }

    after(JTabbedPane tabbedPane):
			execution(public static void StatisticsHelper.StatisticsPaneCreated(JTabbedPane))
			&& args(tabbedPane) {
        panel.setLayout(new GridLayout(2, 2));

        updateData();
        panel.add(new InteractivePanel(createExpGameBarPlot()));
        panel.add(new InteractivePanel(createWonGamesBarPlot()));
        panel.add(new InteractivePanel(createPlayedTypesPlot()));

        tabbedPane.addTab("Gesamtstatistiken (Grafik)", panel);
    }

    after() : execution(* UIUpdater.run()) {
        updateData();
    }

    private static void updateData() {
        OverallStatistics data = gui.model.getGameData().getOverallStatistics();

        while (playedTypes.getRowCount() > 0) {
            playedTypes.removeLast();
        }
        playedTypes.add(data.getAnzahlRufspiele(), "Rufspiele");
        playedTypes.add(data.getAnzahlSoli(), "Soli");
        playedTypes.add(data.getAnzahlSoliTout(), "Soli Tout");
        playedTypes.add(data.getAnzahlSoliSie(), "Soli Sie");
        playedTypes.add(data.getAnzahlWeiter(), "Weiter");

        while (mostExpsvGame.getRowCount() > 0) {
            mostExpsvGame.removeLast();
        }
        mostExpsvGame.add(1, data.getTeuerstesRufspiel(), "Rufspiel");
        mostExpsvGame.add(2, data.getTeuerstesSolo(), "Solo");
        mostExpsvGame.add(3, data.getTeuerstesSoloTout(), "Solo Tout");
        mostExpsvGame.add(4, data.getTeuerstesSoloSie(), "Solo Sie");

        while (wonGames.getRowCount() > 0) {
            wonGames.removeLast();
        }
        wonGames.add(1, data.getGesamtWinPerc(), "Gesamt");
        wonGames.add(2, data.getRufspieleWinPerc(), "Rufspiele");
        wonGames.add(3, data.getSoliGesamtWinPerc(), "Soli gesamt");
        wonGames.add(4, data.getSoliNormalWinPerc(), "Soli normal");
        wonGames.add(5, data.getSoliToutWinPerc(), "Soli Tout");
        wonGames.add(6, data.getSoliSieWinPerc(), "Soli Sie");
    }

    private static PiePlot createPlayedTypesPlot() {
        PiePlot plot = new PiePlot(playedTypes);

        PointRenderer pointRenderer = plot.getPointRenderer(playedTypes);
        pointRenderer.setValueVisible(true);
        pointRenderer.setValueColumn(1);

        // Format plot
        plot.getTitle().setText("Anzahl gespielter Spieltypen");
        // Change plot size
        plot.setRadius(0.9);
        // Display a legend
        plot.setLegendVisible(true);
        // Add some margin to the plot area
        plot.setInsets(new Insets2D.Double(20.0, 40.0, 40.0, 40.0));

        PieSliceRenderer pieSliceRenderer = (PieSliceRenderer) plot
                .getPointRenderer(playedTypes);

        // Change relative size of inner region
        pieSliceRenderer.setInnerRadius(0.4);
        // Change the width of gaps between segments
        pieSliceRenderer.setGap(0.2);
        // Show labels
        pieSliceRenderer.setValueVisible(true);
        pieSliceRenderer.setValueColor(Color.WHITE);
        pieSliceRenderer.setValueFont(Font.decode(null).deriveFont(Font.BOLD));

        return plot;
    }

    public BarPlot createExpGameBarPlot() {
        // Create new bar plot
        BarPlot plot = new BarPlot(mostExpsvGame);

        // Format plot
        plot.getTitle().setText("Teuerstes Spiel pro Spieltyp");
        plot.setInsets(new Insets2D.Double(40.0, 40.0, 40.0, 40.0));
        plot.setBarWidth(0.075);

        // Format bars
        PointRenderer pointRenderer = plot.getPointRenderer(mostExpsvGame);
        BarRenderer barRenderer = (BarRenderer) pointRenderer;

        barRenderer.setColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] { COLOR1,
                        GraphicsUtils.deriveBrighter(COLOR1) }));
        barRenderer.setBorderStroke(new BasicStroke(3f));
        barRenderer.setBorderColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] {
                        GraphicsUtils.deriveBrighter(COLOR1), COLOR1 }));

        pointRenderer.setValueVisible(true);
        pointRenderer.setValueColumn(2);

        pointRenderer.setValueLocation(Location.CENTER);
        pointRenderer.setValueColor(GraphicsUtils.deriveDarker(COLOR1));
        pointRenderer.setValueFont(Font.decode(null).deriveFont(Font.BOLD));

        return plot;
    }

    public BarPlot createWonGamesBarPlot() {
        // Create new bar plot
        BarPlot plot = new BarPlot(wonGames);

        // Format plot
        plot.getTitle().setText("Gewonnene Spiele pro Spieltyp (in %)");
        plot.setInsets(new Insets2D.Double(40.0, 40.0, 40.0, 40.0));
        plot.setBarWidth(0.075);

        // Format bars
        PointRenderer pointRenderer = plot.getPointRenderer(wonGames);
        BarRenderer barRenderer = (BarRenderer) pointRenderer;

        barRenderer.setColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] { COLOR1,
                        GraphicsUtils.deriveBrighter(COLOR1) }));
        barRenderer.setBorderStroke(new BasicStroke(3f));
        barRenderer.setBorderColor(new LinearGradientPaint(0f, 0f, 0f, 1f,
                new float[] { 0.0f, 1.0f }, new Color[] {
                        GraphicsUtils.deriveBrighter(COLOR1), COLOR1 }));

        pointRenderer.setValueVisible(true);
        pointRenderer.setValueColumn(2);

        pointRenderer.setValueLocation(Location.CENTER);
        pointRenderer.setValueColor(GraphicsUtils.deriveDarker(COLOR1));
        pointRenderer.setValueFont(Font.decode(null).deriveFont(Font.BOLD));

        return plot;
    }
}


System.exit(0) in case of strong failure

package benchmark.competition.java.javaMOP;

import monitoring.impl.MonitorFactory;
import monitoring.intf.Monitor;
import properties.Property;
import properties.competition.JavaMOP;
import structure.impl.other.Verdict;
import structure.intf.QEA;

public aspect JavaMOPThreeAspect {

	private final Monitor monitor;

	private final int A = 1;
	private final int B = 2;
	private final int C = 3;

	public JavaMOPThreeAspect() {
		QEA qea = new JavaMOP().make(Property.JAVAMOP_THREE);
		monitor = MonitorFactory.create(qea);
	}

	pointcut A() : call(void CThread2.A());

	pointcut B() : call(void CThread2.B());

	pointcut C() : call(void CThread2.C());

	before() : A() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(A);
		}
		if (verdict == Verdict.FAILURE) {
			System.err
					.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
			System.exit(0);
		}
	}

	before() : B() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(B);
		}
		if (verdict == Verdict.FAILURE) {
			System.err
					.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
			System.exit(0);
		}
	}

	before() : C() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(C);
		}
		if (verdict == Verdict.FAILURE) {
			System.err
					.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
			System.exit(0);
		}
	}

	pointcut endOfProgram() : execution(void SRSTest.main(String[]));

	after() : endOfProgram() {
		Verdict verdict = monitor.end();
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
		} else {
			System.err.println("Property JavaMOP 3 satisfied");
		}
	}
}

package benchmark.competition.java.javaMOP;

import monitoring.impl.MonitorFactory;
import monitoring.intf.Monitor;
import properties.Property;
import properties.competition.JavaMOP;
import structure.impl.other.Verdict;
import structure.intf.QEA;

public aspect JavaMOPThreeAspect {

	private final Monitor monitor;

	private final int A = 1;
	private final int B = 2;
	private final int C = 3;

	public JavaMOPThreeAspect() {
		QEA qea = new JavaMOP().make(Property.JAVAMOP_THREE);
		monitor = MonitorFactory.create(qea);
	}

	pointcut A() : call(void CThread2.A());

	pointcut B() : call(void CThread2.B());

	pointcut C() : call(void CThread2.C());

	before() : A() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(A);
		}
		if (verdict == Verdict.FAILURE) {
			System.err
			.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
		}
	}

	before() : B() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(B);
		}
		if (verdict == Verdict.FAILURE) {
			System.err
			.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
		}
	}

	before() : C() {
		Verdict verdict;
		synchronized (monitor) {
			verdict = monitor.step(C);
		}
		if (verdict == Verdict.FAILURE) {
			System.err
			.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
		}
	}

	pointcut endOfProgram() : execution(void SRSTest.main(String[]));

	after() : endOfProgram() {
		Verdict verdict = monitor.end();
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JavaMOP 3. The functions A(), B(), C() must be called equal times.");
		} else {
			System.err.println("Property JavaMOP 3 satisfied");
		}
	}
}


Corrected grammar and layout issues in Javadoc.

git-svn-id: b619a0c99665f88f1afe72824344cefe9a1c8c90@15327 fd5a2b45-1f63-4059-99e9-3c7cb7fd75c8

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.aspectj;

import java.io.ObjectStreamException;
import java.io.Serializable;

import org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver;
import org.springframework.beans.factory.annotation.Configurable;

/**
 * Concrete aspect that uses the {@link Configurable }
 * annotation to identify which classes need autowiring.
 *
 *
The bean name to look up will be taken from the
 * @Configurable annotation if specified, otherwise the
 * default bean name to look up will be the FQN of the class being configured.
 *
 *
Implementation details:

 *
 *
This aspect advises object creation for @Configurable
 * class instances. There are two cases that needs to be handled:
 *
 *

 *
Normal object creation via the 'new' operator: this is
 *       taken care of by advising initialization() join points.

 *
Object creation through deserialization: since no constructor is
 *       invoked during deserialization, the aspect needs to advise a method that a
 *       deserialization mechanism is going to invoke. Ideally, we should not
 *       require user classes to implement any specific method. This implies that
 *       we need to introduce the chosen method. We should also handle the cases
 *       where the chosen method is already implemented in classes (in which case,
 *       the user's implementation for that method should take precedence over the
 *       introduced implementation). There are a few choices for the chosen method:
 *

 *
readObject(ObjectOutputStream): Java requires that the method must be
 *           private
. Since aspects cannot introduce a private member,
 *           while preserving its name, this option is ruled out.

 *
readResolve(): Java doesn't pose any restriction on an access specifier.
 *           Problem solved! There is one (minor) limitation of this approach in
 *           that if a user class already has this method, that method must be
 *           public. However, this shouldn't be a big burden, since
 *           use cases that need classes to implement readResolve() (custom enums,
 *           for example) are unlikely to be marked as @Configurable, and
 *           in any case asking to make that method public should not
 *           pose any undue burden.

 *

 *       The minor collaboration needed by user classes (i.e., that the
 *       implementation of readResolve(), if any, must be
 *       public) can be lifted as well if we were to use an
 *       experimental feature in AspectJ - the hasmethod() PCD.

 *

 *
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @author Adrian Colyer
 * @since 2.0
 * @see org.springframework.beans.factory.annotation.Configurable
 * @see org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver
 */
public aspect AnnotationBeanConfigurerAspect extends AbstractBeanConfigurerAspect {

	/**
	 * Create a new instance of the AnnotationBeanConfigurerAspect
	 * aspect that uses an {@link AnnotationBeanWiringInfoResolver}.
	 */
	public AnnotationBeanConfigurerAspect() {
		setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
	}

	/**
	 * The initialization of a new object where the class of the object
	 * to be constructed is annotated with the @Configurable
	 * annotation.
	 *
	 *
Besides selecting the normal construction using initialize(),
	 * it also picks out the readResolve() method in Serializable+.
	 *
	 *
Additionally, this pointcut filters out any creation that does not
	 * correspond to the most specific class of the object (and not any of the
	 * base classes in the hierarchy). This avoids repeated re-configuration of
	 * a bean with a base type that is also annotated with the
	 * @Configurable annotation (see SPR-2485).
	 *
	 *
See implementation detail in aspect's documentation.
	 */
	protected pointcut beanCreation(Object beanInstance) :
		 ( mostSpecificInitializer() ||
		   configurableObjectResolution() )
		 && this(beanInstance);

	/**
	 * The initialization of a new object where the class of the object
	 * to be constructed is annotated with the @Configurable
	 * annotation.
	 *
	 *
This pointcut selects the initialization corresponding to
	 * a constructor of the top-most class that has @Configurable.
	 * Any constructor of such base class will not have properties
	 * injected to be used in the constructor. This design decision is
	 * guided by the fact that such base class' constructors should not be
	 * expecting to be injected since a non-@Configurable subtype
	 * will easily invalidate any such expectation.
	 */
	protected pointcut beanInitialization(Object beanInstance) :
		initialization((@Configurable *)+.new(..)) && this(beanInstance);

	/**
	 * Are dependencies to be injected prior to the construction of an object?
	 */
	protected boolean preConstructionConfiguration(Object beanInstance) {
		Configurable configurable = beanInstance.getClass().getAnnotation(Configurable.class);
		return configurable.preConstruction();
	}

	/**
	 * Matches the most-specific initialization join point
	 * (most concrete class) for the initialization of an instance
	 * of an @Configurable type.
	 */
	private pointcut mostSpecificInitializer() :
		initialization((@Configurable *)+.new(..)) &&
		if(thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());

	/**
	 * Matches the readResolve execution join point for a serializable
	 * type that is also @Configurable.
	 */
	private pointcut configurableObjectResolution() :
		execution(Object ConfigurableDeserializationSupport+.readResolve() throws ObjectStreamException) &&
		@this(Configurable);

	/**
	 * Declare any class implementing Serializable annotated with
	 * @Configurable as also implementing ConfigurableDeserializationSupport.
	 * This allows us to introduce the readResolve() method and select it with the
	 * beanCreation() pointcut.
	 *
	 *
Here is an improved version that uses the hasmethod() pointcut and lifts
	 * even the minor requirement on user classes:
	 *
	 *
declare parents: @Configurable Serializable+
	 *		            && !hasmethod(Object readResolve() throws ObjectStreamException)
	 *		            implements ConfigurableDeserializationSupport;
	 *

     *
	 */
	declare parents: @Configurable Serializable+
			       implements ConfigurableDeserializationSupport;

	/**
	 * A marker interface to which the readResolve() is introduced.
	 */
	interface ConfigurableDeserializationSupport extends Serializable {
	}

	/**
	 * Introduce the readResolve() method so that we can advise its
	 * execution to configure the object.
	 *
	 *
Note if a method with the same signature already exists in a
	 * Serializable class annotated with @Configurable,
	 * that implementation will take precedence (a good thing, since we are
	 * merely interested in an opportunity to detect deserialization.)
	 */
	public Object ConfigurableDeserializationSupport.readResolve() throws ObjectStreamException {
		return this;
	}

}

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.aspectj;

import java.io.ObjectStreamException;
import java.io.Serializable;

import org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver;
import org.springframework.beans.factory.annotation.Configurable;

/**
 * Concrete aspect that uses the {@link Configurable }
 * annotation to identify which classes need autowiring.
 *
 *
The bean name to look up will be taken from the
 * @Configurable annotation if specified, otherwise the
 * default bean name to look up will be the FQN of the class being configured.
 *
 *
Implementation details:

 *
 *
This aspect advises object creation for @Configurable
 * class instances. There are two cases that needs to be handled:
 *
 *

 *
Normal object creation via the 'new' operator: this is
 *       taken care of by advising initialization() join points.

 *
Object creation through deserialization: since no constructor is
 *       invoked during deserialization, the aspect needs to advise a method that a
 *       deserialization mechanism is going to invoke. Ideally, we should not
 *       require user classes to implement any specific method. This implies that
 *       we need to introduce the chosen method. We should also handle the cases
 *       where the chosen method is already implemented in classes (in which case,
 *       the users implementation for that method should take precedence over the
 *       introduced implementation). There are a few choices for the chosen method:
 *

 *
readObject(ObjectOutputStream): Java requires that the method must be
 *           private
. Since aspects cannot introduce a private member,
 *           while preserving its name, this option is ruled out.

 *
readResolve(): Java doesn't pose any restriction on access specifier.
 *           Problem solved! There is one (minor) limitation of this approach in
 *           that if a user class already has this method, that method must be
 *           public. However, this shouldn't be a big burden, since
 *           use cases that need classes to implement readResolve() (custom enums,
 *           for example) are unlikely to be marked as @Configurable
, and
 *           in any case asking to make that method public should not
 *           pose any undue burden.
 *

 *       The minor collaboration needed by user classes (the implementation of
 *       readResolve(), if any, must be public) can be
 *       lifted as well if we were to use experimental feature in AspectJ - the
 *       hasmethod() PCD.
 *

 *
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @author Adrian Colyer
 * @since 2.0
 * @see org.springframework.beans.factory.annotation.Configurable
 * @see org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver
 */
public aspect AnnotationBeanConfigurerAspect extends AbstractBeanConfigurerAspect {

	/**
	 * Create a new instance of the AnnotationBeanConfigurerAspect
	 * aspect that uses an {@link AnnotationBeanWiringInfoResolver}.
	 */
	public AnnotationBeanConfigurerAspect() {
		setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
	}

	/**
	 * The initialization of a new object where the class of the object
	 * to be constructed is annotated with the @Configurable
	 * annotation.
	 *
	 *
Besides selecting the normal construction using initialize(),
	 * it also picks out the readResolve() method in Serializable+.
	 *
	 *
Additionally, this pointcut filters out any creation that does not
	 * correspond to the most specific class of the object (and not any of the
	 * base classes in the hierarchy). This avoids repeated re-configuration of
	 * a bean with a base type that is also annotated with the
	 * @Configurable annotation (see SPR-2485).
	 *
	 *
See implementation detail in aspect's documentation.
	 */
	protected pointcut beanCreation(Object beanInstance) :
		 ( mostSpecificInitializer() ||
		   configurableObjectResolution() )
		 && this(beanInstance);

	/**
	 * The initialization of a new object where the class of the object
	 * to be constructed is annotated with the @Configurable
	 * annotation.
	 *
	 *
This pointcut selects the initialization corresponding to
	 * a constructor of the top-most class that has @Configurable.
	 * Any constructor of such base class will not have properties
	 * injected to be used in the constructor. This design decision is
	 * guided by the fact that such base class' constructors should not be
	 * expecting to be injected since a non-@Configurable subtype
	 * will easily invalidate any such expectation.
	 */
	protected pointcut beanInitialization(Object beanInstance) :
		initialization((@Configurable *)+.new(..)) && this(beanInstance);

	/**
	 * Are dependencies to be injected prior to the construction of an object?
	 */
	protected boolean preConstructionConfiguration(Object beanInstance) {
		Configurable configurable = beanInstance.getClass().getAnnotation(Configurable.class);
		return configurable.preConstruction();
	}

	/**
	 * Matches the most-specific initialization join point
	 * (most concrete class) for the initialization of an instance
	 * of an @Configurable type.
	 */
	private pointcut mostSpecificInitializer() :
		initialization((@Configurable *)+.new(..)) &&
		if(thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());

	/**
	 * Matches the readResolve execution join point for a serializable
	 * type that is also @Configurable.
	 */
	private pointcut configurableObjectResolution() :
		execution(Object ConfigurableDeserializationSupport+.readResolve() throws ObjectStreamException) &&
		@this(Configurable);

	/**
	 * Declare any class implementing Serializable annotated with
	 * @Configurable as also implementing ConfigurableDeserializationSupport.
	 * This allows us to introduce the readResolve() method and select it with the
	 * beanCreation() pointcut.
	 *
	 *
Here is an improved version that uses the hasmethod() pointcut and lifts
	 * even the minor requirement on user classes:
	 *
	 *
declare parents: @Configurable Serializable+
	 *		            && !hasmethod(Object readResolve() throws ObjectStreamException)
	 *		            implements ConfigurableDeserializationSupport;
	 *

     *
	 */
	declare parents: @Configurable Serializable+
			       implements ConfigurableDeserializationSupport;

	/**
	 * A marker interface to which the readResolve() is introduced.
	 */
	interface ConfigurableDeserializationSupport extends Serializable {
	}

	/**
	 * Introduce the readResolve() method so that we can advise its
	 * execution to configure the object.
	 *
	 *
Note if a method with the same signature already exists in a
	 * Serializable class annotated with @Configurable,
	 * that implementation will take precedence (a good thing, since we are
	 * merely interested in an opportunity to detect deserialization.)
	 */
	public Object ConfigurableDeserializationSupport.readResolve() throws ObjectStreamException {
		return this;
	}

}


Restrict method visibility

Restrict method visibility

/**
 * Copyright (C) 2013 Antonin Stefanutti (antonin.stefanutti@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fr.stefanutti.metrics.aspectj;

import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.annotation.ExceptionMetered;
import com.codahale.metrics.annotation.Gauge;
import com.codahale.metrics.annotation.Metered;
import com.codahale.metrics.annotation.Timed;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

abstract aspect AbstractMetricAspect {

    protected interface MetricFactory {
        Metric metric(MetricRegistry registry, String name, boolean absolute);
    }

    protected static String metricAnnotationName(Annotation annotation) {
        if (Gauge.class.isInstance(annotation))
            return ((Gauge) annotation).name();
        else if (ExceptionMetered.class.isInstance(annotation))
            return ((ExceptionMetered) annotation).name();
        else if (Metered.class.isInstance(annotation))
            return ((Metered) annotation).name();
        else if (Timed.class.isInstance(annotation))
            return ((Timed) annotation).name();
        else
            throw new IllegalArgumentException("Unsupported Metrics annotation [" + annotation.getClass().getName() + "]");
    }

    protected static boolean metricAnnotationAbsolute(Annotation annotation) {
        if (Gauge.class.isInstance(annotation))
            return ((Gauge) annotation).absolute();
        else if (ExceptionMetered.class.isInstance(annotation))
            return ((ExceptionMetered) annotation).absolute();
        else if (Metered.class.isInstance(annotation))
            return ((Metered) annotation).absolute();
        else if (Timed.class.isInstance(annotation))
            return ((Timed) annotation).absolute();
        else
            throw new IllegalArgumentException("Unsupported Metrics annotation [" + annotation.getClass().getName() + "]");
    }

    protected static class ForwardingGauge implements com.codahale.metrics.Gauge<Object> {

        final Method method;
        final Object object;

        protected ForwardingGauge(Method method, Object object) {
            this.method = method;
            this.object = object;
            method.setAccessible(true);
        }

        @Override
        public Object getValue() {
            // TODO: use more efficient technique than reflection
            return invokeMethod(method, object);
        }
    }

    private static Object invokeMethod(Method method, Object object) {
        try {
            return method.invoke(object);
        } catch (IllegalAccessException cause) {
            throw new IllegalStateException("Error while calling method [" + method + "]", cause);
        } catch (InvocationTargetException cause) {
            throw new IllegalStateException("Error while calling method [" + method + "]", cause);
        }
    }
}

/**
 * Copyright (C) 2013 Antonin Stefanutti (antonin.stefanutti@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package fr.stefanutti.metrics.aspectj;

import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.annotation.ExceptionMetered;
import com.codahale.metrics.annotation.Gauge;
import com.codahale.metrics.annotation.Metered;
import com.codahale.metrics.annotation.Timed;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

abstract aspect AbstractMetricAspect {

    protected interface MetricFactory {
        Metric metric(MetricRegistry registry, String name, boolean absolute);
    }

    protected static String metricAnnotationName(Annotation annotation) {
        if (Gauge.class.isInstance(annotation))
            return ((Gauge) annotation).name();
        else if (ExceptionMetered.class.isInstance(annotation))
            return ((ExceptionMetered) annotation).name();
        else if (Metered.class.isInstance(annotation))
            return ((Metered) annotation).name();
        else if (Timed.class.isInstance(annotation))
            return ((Timed) annotation).name();
        else
            throw new IllegalArgumentException("Unsupported Metrics annotation [" + annotation.getClass().getName() + "]");
    }

    protected static boolean metricAnnotationAbsolute(Annotation annotation) {
        if (Gauge.class.isInstance(annotation))
            return ((Gauge) annotation).absolute();
        else if (ExceptionMetered.class.isInstance(annotation))
            return ((ExceptionMetered) annotation).absolute();
        else if (Metered.class.isInstance(annotation))
            return ((Metered) annotation).absolute();
        else if (Timed.class.isInstance(annotation))
            return ((Timed) annotation).absolute();
        else
            throw new IllegalArgumentException("Unsupported Metrics annotation [" + annotation.getClass().getName() + "]");
    }

    // TODO: should be made private (impact unit tests that use reflection to call the getValue() method)
    public static class ForwardingGauge implements com.codahale.metrics.Gauge<Object> {

        final Method method;
        final Object object;

        protected ForwardingGauge(Method method, Object object) {
            this.method = method;
            this.object = object;
            method.setAccessible(true);
        }

        @Override
        public Object getValue() {
            // TODO: use more efficient technique than reflection
            return invokeMethod(method, object);
        }
    }

    private static Object invokeMethod(Method method, Object object) {
        try {
            return method.invoke(object);
        } catch (IllegalAccessException cause) {
            throw new IllegalStateException("Error while calling method [" + method + "]", cause);
        } catch (InvocationTargetException cause) {
            throw new IllegalStateException("Error while calling method [" + method + "]", cause);
        }
    }
}