<commit_before>/*
 *
 * Copyright 2014 Applied Visions
 *
 * 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.jenkinsci.plugins.codedx;

import com.secdec.codedx.api.client.*;
import com.secdec.codedx.api.client.Job;
import com.secdec.codedx.api.client.Project;
import com.secdec.codedx.security.JenkinsSSLConnectionSocketFactoryFactory;
import com.secdec.codedx.util.CodeDxVersion;
import hudson.AbortException;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Extension;
import hudson.model.*;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import jenkins.tasks.SimpleBuildStep;
import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.jenkinsci.plugins.codedx.model.CodeDxReportStatistics;
import org.jenkinsci.plugins.codedx.model.CodeDxGroupStatistics;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;
import org.jenkinsci.plugins.tokenmacro.TokenMacro;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.QueryParameter;

import javax.net.ssl.SSLHandshakeException;
import javax.servlet.ServletException;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.*;
import java.util.logging.Logger;

/**
 * Jenkins publisher that publishes project source, binaries, and
 * analysis tool output files to a CodeDx server.
 *
 * @author anthonyd
 */
public class CodeDxPublisher extends Recorder implements SimpleBuildStep, Serializable {

	private final String url;
	private final String key;
	private final String projectId;

	private final String sourceAndBinaryFiles;
	private final String toolOutputFiles;
	private final String excludedSourceAndBinaryFiles;
	private final String analysisName;

	private final AnalysisResultConfiguration analysisResultConfiguration;

	private transient CodeDxClient client;

	private final String selfSignedCertificateFingerprint;

	private final static Logger logger = Logger.getLogger(CodeDxPublisher.class.getName());

	/**
	 * @param url                          URL of the Code Dx server
	 * @param key                          API key of the Code Dx server
	 * @param projectId                    Code Dx project ID
	 * @param sourceAndBinaryFiles         Comma separated list of source/binary file Ant GLOB patterns
	 * @param toolOutputFiles              List of paths to tool output files
	 * @param excludedSourceAndBinaryFiles Comma separated list of source/binary file Ant GLOB patterns to exclude
	 * @param analysisResultConfiguration  Contains the fields applicable when the user chooses to have Jenkins wait for
	 *                                     analysis runs to complete.
	 */
	@DataBoundConstructor
	public CodeDxPublisher(
			final String url,
			final String key,
			final String projectId,
			final String sourceAndBinaryFiles,
			final String toolOutputFiles,
			final String excludedSourceAndBinaryFiles,
			final String analysisName,
			final AnalysisResultConfiguration analysisResultConfiguration,
			final String selfSignedCertificateFingerprint
	) {
		this.projectId = projectId;
		this.url = url;
		this.key = key;
		this.sourceAndBinaryFiles = sourceAndBinaryFiles;
		this.excludedSourceAndBinaryFiles = excludedSourceAndBinaryFiles;
		this.toolOutputFiles = toolOutputFiles;
		this.analysisName = analysisName.trim();
		this.analysisResultConfiguration = analysisResultConfiguration;
		this.selfSignedCertificateFingerprint = selfSignedCertificateFingerprint;
		setupClient();
	}

	private void setupClient() {
		if (this.client == null) {
			this.client = buildClient(url, key, selfSignedCertificateFingerprint);
		}
	}

	public AnalysisResultConfiguration getAnalysisResultConfiguration() {
		return analysisResultConfiguration;
	}

	public String getProjectId() {
		return projectId;
	}

	public String getUrl() {

		return url;
	}

	public String getKey() {

		return key;
	}

	public String getSourceAndBinaryFiles() {
		return sourceAndBinaryFiles;
	}


	public String getToolOutputFiles() {
		return toolOutputFiles;
	}

	public String getExcludedSourceAndBinaryFiles() {
		return excludedSourceAndBinaryFiles;
	}

	public String getSelfSignedCertificateFingerprint() {
		return selfSignedCertificateFingerprint;
	}

	public String getAnalysisName(){ return analysisName; }

	private String getLatestAnalysisUrl() {
		if (projectId.length() != 0 && !projectId.equals("-1")) {
			setupClient();
			return client.buildLatestFindingsUrl(Integer.parseInt(projectId));
		} else {
			return null;
		}
	}

	@Override
	public void perform(
			final Run<?, ?> build,
			final FilePath workspace,
			final Launcher launcher,
			final TaskListener listener) throws InterruptedException, IOException {

		Date startingDate = new Date();

		setupClient();
		final Map<String, InputStream> toSend = new HashMap<String, InputStream>();
		final PrintStream buildOutput = listener.getLogger();

		buildOutput.println("Publishing build to Code Dx:");

		if (projectId.length() == 0 || projectId.equals("-1")) {
<commit_msg>Remove unnecessary properties from ctor and move to setters<commit_after>/*
 *
 * Copyright 2014 Applied Visions
 *
 * 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.jenkinsci.plugins.codedx;

import com.secdec.codedx.api.client.*;
import com.secdec.codedx.api.client.Job;
import com.secdec.codedx.api.client.Project;
import com.secdec.codedx.security.JenkinsSSLConnectionSocketFactoryFactory;
import com.secdec.codedx.util.CodeDxVersion;
import hudson.AbortException;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Extension;
import hudson.model.*;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import jenkins.tasks.SimpleBuildStep;
import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.jenkinsci.plugins.codedx.model.CodeDxReportStatistics;
import org.jenkinsci.plugins.codedx.model.CodeDxGroupStatistics;
import org.jenkinsci.plugins.tokenmacro.MacroEvaluationException;
import org.jenkinsci.plugins.tokenmacro.TokenMacro;
import org.kohsuke.stapler.*;

import javax.net.ssl.SSLHandshakeException;
import javax.servlet.ServletException;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.*;
import java.util.logging.Logger;

/**
 * Jenkins publisher that publishes project source, binaries, and
 * analysis tool output files to a CodeDx server.
 *
 * @author anthonyd
 */
public class CodeDxPublisher extends Recorder implements SimpleBuildStep, Serializable {

	private final String url;
	private final String key;
	private final String projectId;

	// Comma separated list of source/binary file Ant GLOB patterns
	private String sourceAndBinaryFiles;
	// List of paths to tool output files
	private String toolOutputFiles;
	// Comma separated list of source/binary file Ant GLOB patterns to exclude
	private String excludedSourceAndBinaryFiles;

	private String analysisName;

	// Contains the fields applicable when the user chooses to have Jenkins wait for
	// analysis runs to complete.
	private AnalysisResultConfiguration analysisResultConfiguration;

	private transient CodeDxClient client;

	private String selfSignedCertificateFingerprint;

	private final static Logger logger = Logger.getLogger(CodeDxPublisher.class.getName());

	/**
	 * @param url                          URL of the Code Dx server
	 * @param key                          API key of the Code Dx server
	 * @param projectId                    Code Dx project ID
	 */
	@DataBoundConstructor
	public CodeDxPublisher(
			final String url,
			final String key,
			final String projectId,
			final String analysisName
	) {
		this.projectId = projectId;
		this.url = url;
		this.key = key;
		this.analysisName = analysisName.trim();

		this.sourceAndBinaryFiles = "";
		this.excludedSourceAndBinaryFiles = "";
		this.toolOutputFiles = "";
		this.analysisResultConfiguration = null;
		this.selfSignedCertificateFingerprint = null;

		setupClient();
	}

	private void setupClient() {
		if (this.client == null) {
			this.client = buildClient(url, key, selfSignedCertificateFingerprint);
		}
	}

	public AnalysisResultConfiguration getAnalysisResultConfiguration() {
		return analysisResultConfiguration;
	}

	@DataBoundSetter
	public void setAnalysisResultConfiguration(AnalysisResultConfiguration analysisResultConfiguration) {
		this.analysisResultConfiguration = analysisResultConfiguration;
	}

	public String getProjectId() {
		return projectId;
	}

	public String getUrl() {
		return url;
	}

	public String getKey() {
		return key;
	}

	public String getSourceAndBinaryFiles() {
		return sourceAndBinaryFiles;
	}

	@DataBoundSetter
	public void setSourceAndBinaryFiles(String sourceAndBinaryFiles) {
		this.sourceAndBinaryFiles = sourceAndBinaryFiles;
	}

	public String getToolOutputFiles() {
		return toolOutputFiles;
	}

	@DataBoundSetter
	public void setToolOutputFiles(String toolOutputFiles) {
		this.toolOutputFiles = toolOutputFiles;
	}

	public String getExcludedSourceAndBinaryFiles() {
		return excludedSourceAndBinaryFiles;
	}

	@DataBoundSetter
	public void setExcludedSourceAndBinaryFiles(String excludedSourceAndBinaryFiles) {
		this.excludedSourceAndBinaryFiles = excludedSourceAndBinaryFiles;
	}

	public String getSelfSignedCertificateFingerprint() {
		return selfSignedCertificateFingerprint;
	}

	@DataBoundSetter
	public void setSelfSignedCertificateFingerprint(String selfSignedCertificateFingerprint) {
		this.selfSignedCertificateFingerprint = selfSignedCertificateFingerprint;

		this.client = null;
		setupClient();
	}

	public String getAnalysisName(){ return analysisName; }

	private String getLatestAnalysisUrl() {
		if (projectId.length() != 0 && !projectId.equals("-1")) {
			setupClient();
			return client.buildLatestFindingsUrl(Integer.parseInt(projectId));
		} else {
			return null;
		}
	}

	@Override
	public void perform(
			final Run<?, ?> build,
			final FilePath workspace,
			final Launcher launcher,
			final TaskListener listener) throws InterruptedException, IOException {

		Date startingDate = new Date();

		setupClient();
		final Map<String, InputStream> toSend = new HashMap<String, InputStream>();
		final PrintStream buildOutput = listener.getLogger();

		buildOutput.println("Publishing build to Code Dx:");

		if (projectId.length() == 0 || projectId.equals("-1")) {

{'fraction_non_alphanumeric': 0.07877551020408163, 'fraction_numerical': 0.0019591836734693877, 'mean_word_length': 4.773327049952875, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4626438', 'n_tokens_mistral': 3634, 'n_tokens_neox': 3334, 'n_words': 954}