<commit_before>package org.openforis.collect.manager.referencedataimport;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.openforis.collect.manager.process.ProcessStatus;
import org.openforis.commons.collection.CollectionUtils;

/**
 * 
 * @author <NAME>
 *
 */
public abstract class ReferenceDataImportStatus<E extends ParsingError> extends ProcessStatus {
	
	private Map<Long, List<E>> rowToErrors;
	private List<Long> processedRows;
	
	public ReferenceDataImportStatus() {
		super();
		this.processedRows = new ArrayList<Long>();
		this.rowToErrors = new LinkedHashMap<Long, List<E>>();
	}
	
	public void addParsingError(long row, E error) {
		List<E> list = rowToErrors.get(row);
		if ( list == null ) {
			list = new ArrayList<E>();
			rowToErrors.put(row, list);
		}
		if ( ! list.contains(error) ) {
			list.add(error);
		}
	}
	
	public void addParsingError(E error) {
		long row = error.getRow();
		if ( row > 0 ) {
			addParsingError(row, error);
		} else {
			throw new IllegalArgumentException("Error row must be greater than zero");
		}
	}
	
	public void addProcessedRow(long rowNumber) {
		if ( !processedRows.contains(rowNumber)) {
			incrementProcessed();
			processedRows.add(rowNumber);
		}
	}
	
	public List<E> getErrors() {
		Collection<List<E>> errorsPerRows = rowToErrors.values();
		List<E> result = new ArrayList<E>();
		for (List<E> errros : errorsPerRows) {
			result.addAll(errros);
		}
		return result;
	}
	
	public boolean hasErrors() {
		return rowToErrors != null && ! rowToErrors.isEmpty();
	}

	public List<Long> getProcessedRows() {
		return processedRows;
	}
	
	public boolean isRowProcessed(long rowNumber) {
		return processedRows.contains(rowNumber);
	}
	
	public boolean isRowInError(long rowNumber) {
		return rowToErrors.containsKey(rowNumber);
	}
	
	public Collection<Long> getRowsInError() {
		return rowToErrors.keySet();
	}
	
	public List<Long> getSkippedRows() {
		List<Long> result = new ArrayList<Long>();
		for (long i = 1; i <= getTotal(); i++) {
			if ( ! processedRows.contains(i) ) {
				result.add(i);
			}
		}
		return CollectionUtils.unmodifiableList(result);
	}

}<commit_msg>OFC-1239 - Concurrency exception when processing Sampling Design import and reading ReferenceDataImportStatus errors<commit_after>package org.openforis.collect.manager.referencedataimport;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.openforis.collect.manager.process.ProcessStatus;
import org.openforis.commons.collection.CollectionUtils;

/**
 * 
 * @author <NAME>
 *
 */
public abstract class ReferenceDataImportStatus<E extends ParsingError> extends ProcessStatus {
	
	private Map<Long, List<E>> rowToErrors;
	private List<Long> processedRows;
	
	public ReferenceDataImportStatus() {
		super();
		this.processedRows = new ArrayList<Long>();
		this.rowToErrors = new LinkedHashMap<Long, List<E>>();
	}
	
	public synchronized void addParsingError(long row, E error) {
		List<E> list = rowToErrors.get(row);
		if ( list == null ) {
			list = new ArrayList<E>();
			rowToErrors.put(row, list);
		}
		if ( ! list.contains(error) ) {
			list.add(error);
		}
	}
	
	public void addParsingError(E error) {
		long row = error.getRow();
		if ( row > 0 ) {
			addParsingError(row, error);
		} else {
			throw new IllegalArgumentException("Error row must be greater than zero");
		}
	}
	
	public synchronized void addProcessedRow(long rowNumber) {
		if ( !processedRows.contains(rowNumber)) {
			incrementProcessed();
			processedRows.add(rowNumber);
		}
	}
	
	public synchronized List<E> getErrors() {
		Collection<List<E>> errorsPerRows = rowToErrors.values();
		List<E> result = new ArrayList<E>();
		for (List<E> errros : errorsPerRows) {
			result.addAll(errros);
		}
		return result;
	}
	
	public synchronized boolean hasErrors() {
		return rowToErrors != null && ! rowToErrors.isEmpty();
	}

	public synchronized List<Long> getProcessedRows() {
		return processedRows;
	}
	
	public synchronized boolean isRowProcessed(long rowNumber) {
		return processedRows.contains(rowNumber);
	}
	
	public synchronized boolean isRowInError(long rowNumber) {
		return rowToErrors.containsKey(rowNumber);
	}
	
	public synchronized Collection<Long> getRowsInError() {
		return rowToErrors.keySet();
	}
	
	public synchronized List<Long> getSkippedRows() {
		List<Long> result = new ArrayList<Long>();
		for (long i = 1; i <= getTotal(); i++) {
			if ( ! processedRows.contains(i) ) {
				result.add(i);
			}
		}
		return CollectionUtils.unmodifiableList(result);
	}

}
{'fraction_non_alphanumeric': 0.12473302007689022, 'fraction_numerical': 0.0017086715079026058, 'mean_word_length': 4.445348837209302, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 47, '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': '1225723', 'n_tokens_mistral': 1633, 'n_tokens_neox': 1475, 'n_words': 336}