<commit_before>package de.unistuttgart.iste.rss.bugminer.bugs;

import java.io.IOException;
import java.net.URI;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.HashSet;

import org.springframework.beans.factory.annotation.Autowired;

import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.JiraRestClientFactory;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.atlassian.jira.rest.client.api.domain.SearchResult;
import com.atlassian.jira.rest.client.auth.AnonymousAuthenticationHandler;
import com.atlassian.util.concurrent.Promise;
import com.google.common.collect.Iterables;

import de.unistuttgart.iste.rss.bugminer.annotations.Strategy;
import de.unistuttgart.iste.rss.bugminer.model.entities.Bug;
import de.unistuttgart.iste.rss.bugminer.model.entities.IssueTracker;
import de.unistuttgart.iste.rss.bugminer.model.entities.Label;

/**
 * Provides an implementation for the IssueTrackerStrategy interface to use with Jira
 */
@Strategy(name = "jira", type = IssueTrackerStrategy.class)
public class JiraIssueTrackerStrategy implements IssueTrackerStrategy {

	/**
	 * Factory to create JiraRestClient
	 */
	@Autowired
	private JiraRestClientFactory factory;

	protected JiraIssueTrackerStrategy() {
		// managed bean
	}

	/**
	 * Synchronizes with the by issueTracker indicated remote Jira installation
	 */
	@Override
	public Collection<Bug> fetch(IssueTracker issueTracker) throws IOException {
		Collection<Issue> issues = fetchIssues(issueTracker);
		Collection<Bug> fetchedBugs = createBugs(issueTracker, issues);

		return fetchedBugs;
	}

	private Collection<Bug> createBugs(IssueTracker issueTracker, Collection<Issue> issues) {
		Collection<Bug> fetchedBugs = new HashSet<Bug>();

		for (Issue issue : issues) {
			Bug bug = new Bug();


			String closeTimeString = (String) issue.getField("resolutiondate").getValue();
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
			if (closeTimeString != null) {
				Instant closeTime = OffsetDateTime.parse(closeTimeString, formatter).toInstant();
				bug.setCloseTime(closeTime);
			} else {
				bug.setCloseTime(null);
			}


			Instant reportTime = Instant.ofEpochMilli(issue.getCreationDate().getMillis());
			bug.setReportTime(reportTime);

			Collection<Label> labels = new HashSet<Label>();
			// TODO check if labels exist and assign them
			/*
			 * for (String label : issue.getLabels()) { }
			 */
			bug.setLabels(labels);

			bug.setTitle(issue.getSummary());
			bug.setDescription(issue.getDescription());
			bug.setProject(issueTracker.getProject());
			bug.setRepository(issueTracker);

			if (issue.getResolution() != null) {
				bug.setFixed(issue.getResolution().getName().equals("Done")); // TODO
			} else {
				bug.setFixed(false); // not resolved yet
			}
			// TODO: events, participants, jsonDetails

			fetchedBugs.add(bug);
		}

		return fetchedBugs;
	}

	private Collection<Issue> fetchIssues(IssueTracker issueTracker) throws IOException {
		Collection<Issue> issues = new HashSet<Issue>();

		final URI jiraServerUri = issueTracker.getUri();
		final JiraRestClient restClient = factory.create(jiraServerUri,
				new AnonymousAuthenticationHandler());
		final String projectName = issueTracker.getProject().getName();
		final String jqlSearchString = "project=" + projectName;

		Promise<SearchResult> issuePromise = null;

		do {
			issuePromise = restClient.getSearchClient().searchJql(jqlSearchString,
					50, issues.size(), null);

			Iterables.addAll(issues, issuePromise.claim().getIssues());

		} while (Iterables.size(issuePromise.claim().getIssues()) > 0);

		restClient.close();

		return issues;
	}
}<commit_msg>JiraIssueTrackerStrategy restarts request on exception once<commit_after>package de.unistuttgart.iste.rss.bugminer.bugs;

import java.io.IOException;
import java.net.URI;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.HashSet;

import org.springframework.beans.factory.annotation.Autowired;

import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.JiraRestClientFactory;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.atlassian.jira.rest.client.api.domain.SearchResult;
import com.atlassian.jira.rest.client.auth.AnonymousAuthenticationHandler;
import com.atlassian.util.concurrent.Promise;
import com.google.common.collect.Iterables;

import de.unistuttgart.iste.rss.bugminer.annotations.Strategy;
import de.unistuttgart.iste.rss.bugminer.model.entities.Bug;
import de.unistuttgart.iste.rss.bugminer.model.entities.IssueTracker;
import de.unistuttgart.iste.rss.bugminer.model.entities.Label;

/**
 * Provides an implementation for the IssueTrackerStrategy interface to use with Jira
 */
@Strategy(name = "jira", type = IssueTrackerStrategy.class)
public class JiraIssueTrackerStrategy implements IssueTrackerStrategy {

	/**
	 * Factory to create JiraRestClient
	 */
	@Autowired
	private JiraRestClientFactory factory;

	protected JiraIssueTrackerStrategy() {
		// managed bean
	}

	/**
	 * Synchronizes with the by issueTracker indicated remote Jira installation
	 */
	@Override
	public Collection<Bug> fetch(IssueTracker issueTracker) throws IOException {
		Collection<Issue> issues = fetchIssues(issueTracker);
		Collection<Bug> fetchedBugs = createBugs(issueTracker, issues);

		return fetchedBugs;
	}

	private Collection<Bug> createBugs(IssueTracker issueTracker, Collection<Issue> issues) {
		Collection<Bug> fetchedBugs = new HashSet<Bug>();

		for (Issue issue : issues) {
			Bug bug = new Bug();


			String closeTimeString = (String) issue.getField("resolutiondate").getValue();
			DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
			if (closeTimeString != null) {
				Instant closeTime = OffsetDateTime.parse(closeTimeString, formatter).toInstant();
				bug.setCloseTime(closeTime);
			} else {
				bug.setCloseTime(null);
			}


			Instant reportTime = Instant.ofEpochMilli(issue.getCreationDate().getMillis());
			bug.setReportTime(reportTime);

			Collection<Label> labels = new HashSet<Label>();
			// TODO check if labels exist and assign them
			/*
			 * for (String label : issue.getLabels()) { }
			 */
			bug.setLabels(labels);

			bug.setTitle(issue.getSummary());
			bug.setDescription(issue.getDescription());
			bug.setProject(issueTracker.getProject());
			bug.setRepository(issueTracker);

			if (issue.getResolution() != null) {
				bug.setFixed(issue.getResolution().getName().equals("Done")); // TODO
			} else {
				bug.setFixed(false); // not resolved yet
			}
			// TODO: events, participants, jsonDetails

			fetchedBugs.add(bug);
		}

		return fetchedBugs;
	}

	private Collection<Issue> fetchIssues(IssueTracker issueTracker) throws IOException {
		Collection<Issue> issues = new HashSet<Issue>();

		final URI jiraServerUri = issueTracker.getUri();
		final JiraRestClient restClient = factory.create(jiraServerUri,
				new AnonymousAuthenticationHandler());
		final String projectName = issueTracker.getProject().getName();
		final String jqlSearchString = "project=" + projectName;
		boolean exceptionOccured = false;

		Promise<SearchResult> issuePromise = null;

		do {
			try {
				issuePromise = restClient.getSearchClient().searchJql(jqlSearchString,
						50, issues.size(), null);

				Iterables.addAll(issues, issuePromise.claim().getIssues());

			} catch (Exception e) {
				if (exceptionOccured) {
					throw e;
				} else {
					exceptionOccured = true;
					continue;
				}
			}

			exceptionOccured = false;

		} while (Iterables.size(issuePromise.claim().getIssues()) > 0);

		restClient.close();

		return issues;
	}
}
{'fraction_non_alphanumeric': 0.11681236538705182, 'fraction_numerical': 0.0007601672367920942, 'mean_word_length': 4.873511904761905, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4267702', 'n_tokens_mistral': 2668, 'n_tokens_neox': 2350, 'n_words': 462}