<commit_before>package org.juxtalearn.rias.components.visualizationtoserver;

import info.collide.sqlspaces.client.TupleSpace;
import info.collide.sqlspaces.commons.Field;
import info.collide.sqlspaces.commons.Tuple;
import info.collide.sqlspaces.commons.TupleSpaceException;
import info.collide.sqlspaces.commons.util.Base64;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.mozilla.javascript.EvaluatorException;

import com.yahoo.platform.yui.compressor.CssCompressor;

import eu.sisob.components.framework.Agent;
import eu.sisob.components.framework.SISOBProperties;

/* default */ class PlaceHolderFile {
	public String placeholderName;

	public String fileData;
}
/**
 * This Agent sends an assembled visualization to a server specified by a <emph>returnURL</emph>
 * via a POST call with the following parameters:
 * <ul>
 * <li><b>returnId</b> used to map this result to the corresponding analysis request.</li>
 * <li><b>data</b> Base64 encoded analysis result. Most often an HTML snippet that visualizes the result.</li>
 * <li><b>statuscode</b> a status code telling the remote server if the analysis workflow was successful. In case of failure <emph>data</emph> may contain an error message instead of the expected analysis result.</li> 
 * <li><b>auth_token</b> a security token that authenticates this agent against the remote API </li>
 * </ul>
 * @author Malzahn
 * @author Wenzel
 *
 */
public class VisualizationToServer extends Agent {

	private int errorCallbackNo;

	private  String authToken = SISOBProperties.getProperty("components.visualizationtoserver.auth_token", ""); 
	
	public VisualizationToServer(Tuple commandTuple, String serverlocation,
			int port) {
		super(commandTuple, serverlocation, port);
		this.commandTupleStructure = commandTuple;
		Tuple dataTemplate = new Tuple(commandTuple.getField(0).getValue()
				.toString(), 1, commandTuple.getField(5).getValue().toString(),
				Field.createWildCardField());
		setDataTupleStructure(dataTemplate);
	}

	@Override
	public void initializeAgent() {
		super.initializeAgent();
		try {
			// Error: Runid, 5, String String String
			this.errorCallbackNo = sisobspace.eventRegister(Command.WRITE, new Tuple(this.commandTupleStructure.getField(0).getValue().toString(), 5, String.class, String.class, String.class), this, true);
		} catch (TupleSpaceException e) {
			logger.severe(e.getMessage());
		}
	}

	@Override
	public void call(Command cmnd, int callbackNo, Tuple afterTuple, Tuple beforeTuple) {
		if (this.errorCallbackNo==callbackNo) 
			errorHandler(afterTuple);
		else
			super.call(cmnd, callbackNo, afterTuple, beforeTuple);
	}

	private void errorHandler(Tuple fetchedTuple) {
		try {
			TupleSpace ts = new TupleSpace(super.serverLocation, super.port, "ClipitRequests");
			
			//If there are Parameters from NodeWorkbench Visual Komponent, write them to ClipitRequests
			writeParameterTupleToClipitRequests(ts);
			
			String data = fetchedTuple.getField(2).getValue().toString() + " : " + fetchedTuple.getField(3).getValue().toString() + " : " + fetchedTuple.getField(4).getValue().toString();
			
			//get URL and ReturnID Parameter from ClipitRequest Tuple
			Tuple clipitRequestTuple = ts.take(new Tuple(
					this.commandTupleStructure.getField(0).getValue()
							.toString(), String.class, String.class));
			
			if(clipitRequestTuple != null) {
				String url = clipitRequestTuple.getField(1).getValue().toString(); 
						//getPostURL(clipitRequestTuple);
				String returnId = clipitRequestTuple.getField(2).getValue()
						.toString();
				postToURL(url, returnId, data, 5);
			}
			
		} catch (TupleSpaceException e) {
			logger.severe(e.getMessage());
		} catch (IOException e) {
			logger.severe(e.getMessage());
		}
	}
	
	private void writeParameterTupleToClipitRequests(TupleSpace ts) throws TupleSpaceException {
		String parameters = this.getCommandTupleStructure().getField(6)
				.getValue().toString();
		if(parameters.trim() != "") {
			String[] params = parameters.split(",");
			ts.write(new Tuple(this.commandTupleStructure
					.getField(0).getValue().toString(), params[0], params.length>1?params[1]:""));
			if (params.length > 2) {
				if ( !"".equals(params[2].trim())) {
					authToken = params[2];
					
				}
			}
		}
	}
	
	@Override
	public void executeAgent(Tuple fetchedTuple) {
		this.indicateRunning();
		TupleSpace ts = null;
		try {
			// 0 = host
			// 1 = port
			// 2 = Endpoint
			
			String data = generateHTMLData(fetchedTuple);

			 ts = new TupleSpace(super.serverLocation, super.port, "ClipitRequests");
			
			//If there are Parameters from NodeWorkbench Visual Komponent, write them to ClipitRequests
			writeParameterTupleToClipitRequests(ts);
			
			Tuple clipitRequestTuple = ts.take(new Tuple(
					this.commandTupleStructure.getField(0).getValue()
							.toString(), String.class, String.class));

			if (clipitRequestTuple != null) {
				String url = clipitRequestTuple.getField(1).getValue().toString(); 
//						getPostURL(clipitRequestTuple);
				String returnId = clipitRequestTuple.getField(2).getValue()
						.toString();
				String returnValue = postToURL(url, returnId, data, 3);
				logger.fine("Remote server returned:\"" + returnValue +"\"");
			}

			this.indicateDone();

		} catch (JSONException e) {
			this.indicateError(e.getMessage(),e);
			e.printStackTrace();
		} catch (IOException e) {
			this.indicateError(e.getMessage(),e);
			e.printStackTrace();
		} catch (TupleSpaceException e) {
			this.indicateError(e.getMessage(),e);
		}
		finally {
			if ( ts != null ){
				try {
					ts.disconnect();
				} catch (TupleSpaceException e) {
					this.indicateError("TupleSpace shut down failed",e);
				}
			}
		}
	}

	public String postToURL(String urlString, String returnId, String data,
			int status) throws IOException {
		if (!urlString.startsWith("http://")
				&& !urlString.startsWith("https://")) {
			urlString = "http://" + urlString;
		}
		URL url = new URL(urlString);
		logger.finest("Contacting: "+urlString + " ReturnID="+returnId + " statuscode="+status + " auth_token="+authToken);

		String body = "returnId=" + URLEncoder.encode(returnId, "UTF-8") + "&"
				+ "data=" + URLEncoder.encode(Base64.encodeToString(data.getBytes(), true), "UTF-8") + "&"
				+ "statuscode=" + URLEncoder.encode(Integer.toString(status), "UTF-8") +"&" 
				+ "auth_token=" + URLEncoder.encode(authToken,"UTF-8");<commit_msg>added authToken for sending back analysis results.<commit_after>package org.juxtalearn.rias.components.visualizationtoserver;

import info.collide.sqlspaces.client.TupleSpace;
import info.collide.sqlspaces.commons.Field;
import info.collide.sqlspaces.commons.Tuple;
import info.collide.sqlspaces.commons.TupleSpaceException;
import info.collide.sqlspaces.commons.util.Base64;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.mozilla.javascript.EvaluatorException;

import com.yahoo.platform.yui.compressor.CssCompressor;

import eu.sisob.components.framework.Agent;
import eu.sisob.components.framework.SISOBProperties;

/* default */ class PlaceHolderFile {
	public String placeholderName;

	public String fileData;
}
/**
 * This Agent sends an assembled visualization to a server specified by a <emph>returnURL</emph>
 * via a POST call with the following parameters:
 * <ul>
 * <li><b>returnId</b> used to map this result to the corresponding analysis request.</li>
 * <li><b>data</b> Base64 encoded analysis result. Most often an HTML snippet that visualizes the result.</li>
 * <li><b>statuscode</b> a status code telling the remote server if the analysis workflow was successful. In case of failure <emph>data</emph> may contain an error message instead of the expected analysis result.</li> 
 * <li><b>auth_token</b> a security token that authenticates this agent against the remote API </li>
 * </ul>
 * @author Malzahn
 * @author Wenzel
 *
 */
public class VisualizationToServer extends Agent {

	private int errorCallbackNo;

	private  String authToken = SISOBProperties.getProperty("components.visualizationtoserver.auth_token", ""); 
	
	public VisualizationToServer(Tuple commandTuple, String serverlocation,
			int port) {
		super(commandTuple, serverlocation, port);
		this.commandTupleStructure = commandTuple;
		Tuple dataTemplate = new Tuple(commandTuple.getField(0).getValue()
				.toString(), 1, commandTuple.getField(5).getValue().toString(),
				Field.createWildCardField());
		setDataTupleStructure(dataTemplate);
	}

	@Override
	public void initializeAgent() {
		super.initializeAgent();
		try {
			// Error: Runid, 5, String String String
			this.errorCallbackNo = sisobspace.eventRegister(Command.WRITE, new Tuple(this.commandTupleStructure.getField(0).getValue().toString(), 5, String.class, String.class, String.class), this, true);
		} catch (TupleSpaceException e) {
			logger.severe(e.getMessage());
		}
	}

	@Override
	public void call(Command cmnd, int callbackNo, Tuple afterTuple, Tuple beforeTuple) {
		if (this.errorCallbackNo==callbackNo) 
			errorHandler(afterTuple);
		else
			super.call(cmnd, callbackNo, afterTuple, beforeTuple);
	}

	private void errorHandler(Tuple fetchedTuple) {
		try {
			TupleSpace ts = new TupleSpace(super.serverLocation, super.port, "ClipitRequests");
			
			//If there are Parameters from NodeWorkbench Visual Komponent, write them to ClipitRequests
			writeParameterTupleToClipitRequests(ts);
			
			String data = fetchedTuple.getField(2).getValue().toString() + " : " + fetchedTuple.getField(3).getValue().toString() + " : " + fetchedTuple.getField(4).getValue().toString();
			
			//get URL and ReturnID Parameter from ClipitRequest Tuple
			Tuple clipitRequestTuple = ts.take(new Tuple(
					this.commandTupleStructure.getField(0).getValue()
							.toString(), String.class, String.class));
			
			if(clipitRequestTuple != null) {
				String url = clipitRequestTuple.getField(1).getValue().toString(); 
						//getPostURL(clipitRequestTuple);
				String returnId = clipitRequestTuple.getField(2).getValue()
						.toString();
				String authToken = clipitRequestTuple.getField(3).getValue()
                                        .toString();
				postToURL(url, returnId, data, 5,authToken);
			}
			
		} catch (TupleSpaceException e) {
			logger.severe(e.getMessage());
		} catch (IOException e) {
			logger.severe(e.getMessage());
		}
	}
	
	private void writeParameterTupleToClipitRequests(TupleSpace ts) throws TupleSpaceException {
		String parameters = this.getCommandTupleStructure().getField(6)
				.getValue().toString();
		if(parameters.trim() != "") {
			String[] params = parameters.split(",");
			ts.write(new Tuple(this.commandTupleStructure
					.getField(0).getValue().toString(), params[0], params.length>1?params[1]:""));
			if (params.length > 2) {
				if ( !"".equals(params[2].trim())) {
					authToken = params[2];
					
				}
			}
		}
	}
	
	@Override
	public void executeAgent(Tuple fetchedTuple) {
		this.indicateRunning();
		TupleSpace ts = null;
		try {
			// 0 = host
			// 1 = port
			// 2 = Endpoint
			
			String data = generateHTMLData(fetchedTuple);

			 ts = new TupleSpace(super.serverLocation, super.port, "ClipitRequests");
			
			//If there are Parameters from NodeWorkbench Visual Komponent, write them to ClipitRequests
			writeParameterTupleToClipitRequests(ts);
			
			Tuple clipitRequestTuple = ts.take(new Tuple(
					this.commandTupleStructure.getField(0).getValue()
							.toString(), String.class, String.class, String.class));

			if (clipitRequestTuple != null) {
				String url = clipitRequestTuple.getField(1).getValue().toString(); 
//						getPostURL(clipitRequestTuple);
				String returnId = clipitRequestTuple.getField(2).getValue()
						.toString();
				String authToken = clipitRequestTuple.getField(3).getValue().toString();
				String returnValue = postToURL(url, returnId, data, 3,authToken);
				
				logger.fine("Remote server returned:\"" + returnValue +"\"");
			}

			this.indicateDone();

		} catch (JSONException e) {
			this.indicateError(e.getMessage(),e);
			e.printStackTrace();
		} catch (IOException e) {
			this.indicateError(e.getMessage(),e);
			e.printStackTrace();
		} catch (TupleSpaceException e) {
			this.indicateError(e.getMessage(),e);
		}
		finally {
			if ( ts != null ){
				try {
					ts.disconnect();
				} catch (TupleSpaceException e) {
					this.indicateError("TupleSpace shut down failed",e);
				}
			}
		}
	}

	public String postToURL(String urlString, String returnId, String data,
			int status, String authToken) throws IOException {
		if (!urlString.startsWith("http://")
				&& !urlString.startsWith("https://")) {
			urlString = "http://" + urlString;
		}
		URL url = new URL(urlString);
		logger.finest("Contacting: "+urlString + " ReturnID="+returnId + " statuscode="+status + " auth_token="+authToken);

		String body = "returnId=" + URLEncoder.encode(returnId, "UTF-8") + "&"
				+ "data=" + URLEncoder.encode(Base64.encodeToString(data.getBytes(), true), "UTF-8") + "&"
				+ "statuscode=" + URLEncoder.encode(Integer.toString(status), "UTF-8") +"&" 
				+ "auth_token=" + URLEncoder.encode(authToken,"UTF-8");
{'fraction_non_alphanumeric': 0.12936752136752136, 'fraction_numerical': 0.005333333333333333, 'mean_word_length': 4.421052631578948, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 51, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1096065', 'n_tokens_mistral': 5015, 'n_tokens_neox': 4434, 'n_words': 979}