<commit_before>/**
 * This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
 */
package edu.illinois.codingtracker.operations.textchanges;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.text.undo.DocumentUndoManagerRegistry;
import org.eclipse.text.undo.IDocumentUndoManager;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.UIPlugin;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.json.simple.JSONObject;

import edu.illinois.codingtracker.compare.helpers.EditorHelper;
import edu.illinois.codingtracker.helpers.Configuration;
import edu.illinois.codingtracker.helpers.ResourceHelper;
import edu.illinois.codingtracker.operations.OperationLexer;
import edu.illinois.codingtracker.operations.OperationTextChunk;
import edu.illinois.codingtracker.operations.UserOperation;
import edu.oregonstate.cope.clientRecorder.JSONConstants;

/**
 * 
 * @author <NAME>
 * 
 */
@SuppressWarnings("restriction")
public abstract class TextChangeOperation extends UserOperation {

	protected String replacedText;

	protected String newText;

	protected int offset;

	protected int length;
	
	protected String fileName;

	protected String changeOrigin;

	//The following fields are computed during replay, do not serialize/deserialize them!

	public static long lastReplayedTimestamp;

	protected IDocument currentDocument= null;

	protected ISourceViewer currentViewer= null;

	private IFile editedFile= null;

	private boolean isRecordedWhileRefactoring= false;

	public TextChangeOperation() {
		super();
	}

	public TextChangeOperation(DocumentEvent documentEvent, String replacedText) {
		this(documentEvent, replacedText, System.currentTimeMillis());
	}

	public TextChangeOperation(DocumentEvent documentEvent, String replacedText, long timestamp) {
		super(timestamp);
		this.replacedText= replacedText;
		newText= documentEvent.getText();
		offset= documentEvent.getOffset();
		length= documentEvent.getLength();
	}

	public int getOffset() {
		return offset;
	}

	public int getLength() {
		return length;
	}

	public String getReplacedText() {
		return replacedText;
	}

	public String getNewText() {
		return newText;
	}

	public DocumentEvent getDocumentEvent(String initialDocumentText) {
		return new DocumentEvent(new Document(initialDocumentText), offset, length, newText);
	}

	protected IDocumentUndoManager getCurrentDocumentUndoManager() {
		return DocumentUndoManagerRegistry.getDocumentUndoManager(currentDocument);
	}

	@Override
	protected void populateTextChunk(OperationTextChunk textChunk) {
		textChunk.append(replacedText);
		textChunk.append(newText);
		textChunk.append(offset);
		textChunk.append(length);
	}

	@Override
	protected void initializeFrom(OperationLexer operationLexer) {
		replacedText= operationLexer.readString();
		newText= operationLexer.readString();
		offset= operationLexer.readInt();
		length= operationLexer.readInt();
	}
	
	 @Override
	 public void parse(JSONObject value) {
	 	fileName = (String) value.get("entityAddress");
	 	replacedText= "";
	 	newText= (String) value.get("text");
	 	long offsetL = (Long) value.get("offset");
	 	offset= (int) offsetL;  
	 	long lengthL =  (Long) value.get("len");
	 	length= (int)lengthL;
	 	changeOrigin = (String) value.get(JSONConstants.JSON_CHANGE_ORIGIN);
	 }

	@Override
	public void replay() throws BadLocationException, ExecutionException {
		lastReplayedTimestamp= getTime();
		if (isReplayedRefactoring) {
			isRecordedWhileRefactoring= true;
		} else {
			updateCurrentState();
			//preReplay();
			replayTextChange();
			//postReplay();
		}
	}

	/**
	 * This replay is used to emphasize the cursor location.
	 * 
	 * @throws BadLocationException
	 */
	public void splitReplay() throws BadLocationException {
		updateCurrentState();
		preReplay();
	}

	private void preReplay() throws BadLocationException {
		if (!Configuration.isInPostprocessMode) {
			//This is not executed while postprocessing to improve performance.
			currentViewer.revealRange(offset, length > newText.length() ? length : newText.length());
			//This is not executed while postprocessing to avoid USER Objects leak.
			currentViewer.setSelectedRange(offset, length);
		}
		if (!replacedText.equals(currentDocument.get(offset, length))) {
			throw new RuntimeException("Replaced text is not present in the document: " + this);
		}
	}

	private void postReplay() throws BadLocationException {
		if (!Configuration.isInPostprocessMode) {
			//This is not executed while postprocessing to avoid USER Objects leak.<commit_msg>Do not replay text changes in conflict files.<commit_after>/**
 * This file is licensed under the University of Illinois/NCSA Open Source License. See LICENSE.TXT for details.
 */
package edu.illinois.codingtracker.operations.textchanges;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.text.undo.DocumentUndoManagerRegistry;
import org.eclipse.text.undo.IDocumentUndoManager;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.UIPlugin;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.json.simple.JSONObject;

import edu.illinois.codingtracker.compare.helpers.EditorHelper;
import edu.illinois.codingtracker.helpers.Configuration;
import edu.illinois.codingtracker.helpers.ResourceHelper;
import edu.illinois.codingtracker.operations.OperationLexer;
import edu.illinois.codingtracker.operations.OperationTextChunk;
import edu.illinois.codingtracker.operations.UserOperation;
import edu.oregonstate.cope.clientRecorder.JSONConstants;

/**
 * 
 * @author <NAME>
 * 
 */
@SuppressWarnings("restriction")
public abstract class TextChangeOperation extends UserOperation {

	protected String replacedText;

	protected String newText;

	protected int offset;

	protected int length;
	
	protected String fileName;

	protected String changeOrigin;

	//The following fields are computed during replay, do not serialize/deserialize them!

	public static long lastReplayedTimestamp;

	protected IDocument currentDocument= null;

	protected ISourceViewer currentViewer= null;

	private IFile editedFile= null;

	private boolean isRecordedWhileRefactoring= false;

	public TextChangeOperation() {
		super();
	}

	public TextChangeOperation(DocumentEvent documentEvent, String replacedText) {
		this(documentEvent, replacedText, System.currentTimeMillis());
	}

	public TextChangeOperation(DocumentEvent documentEvent, String replacedText, long timestamp) {
		super(timestamp);
		this.replacedText= replacedText;
		newText= documentEvent.getText();
		offset= documentEvent.getOffset();
		length= documentEvent.getLength();
	}

	public int getOffset() {
		return offset;
	}

	public int getLength() {
		return length;
	}

	public String getReplacedText() {
		return replacedText;
	}

	public String getNewText() {
		return newText;
	}

	public DocumentEvent getDocumentEvent(String initialDocumentText) {
		return new DocumentEvent(new Document(initialDocumentText), offset, length, newText);
	}

	protected IDocumentUndoManager getCurrentDocumentUndoManager() {
		return DocumentUndoManagerRegistry.getDocumentUndoManager(currentDocument);
	}

	@Override
	protected void populateTextChunk(OperationTextChunk textChunk) {
		textChunk.append(replacedText);
		textChunk.append(newText);
		textChunk.append(offset);
		textChunk.append(length);
	}

	@Override
	protected void initializeFrom(OperationLexer operationLexer) {
		replacedText= operationLexer.readString();
		newText= operationLexer.readString();
		offset= operationLexer.readInt();
		length= operationLexer.readInt();
	}
	
	 @Override
	 public void parse(JSONObject value) {
	 	fileName = (String) value.get("entityAddress");
	 	replacedText= "";
	 	newText= (String) value.get("text");
	 	long offsetL = (Long) value.get("offset");
	 	offset= (int) offsetL;  
	 	long lengthL =  (Long) value.get("len");
	 	length= (int)lengthL;
	 	changeOrigin = (String) value.get(JSONConstants.JSON_CHANGE_ORIGIN);
	 }

	@Override
	public void replay() throws BadLocationException, ExecutionException {
		
		if (changeIsInAuxiliaryConflictFile(fileName))
			return;
		
		lastReplayedTimestamp= getTime();
		if (isReplayedRefactoring) {
			isRecordedWhileRefactoring= true;
		} else {
			updateCurrentState();
			//preReplay();
			replayTextChange();
			//postReplay();
		}
	}

	private boolean changeIsInAuxiliaryConflictFile(String fileName) {
		return fileName.contains(".java") && !fileName.endsWith(".java");
	}

	/**
	 * This replay is used to emphasize the cursor location.
	 * 
	 * @throws BadLocationException
	 */
	public void splitReplay() throws BadLocationException {
		updateCurrentState();
		preReplay();
	}

	private void preReplay() throws BadLocationException {
		if (!Configuration.isInPostprocessMode) {
			//This is not executed while postprocessing to improve performance.
			currentViewer.revealRange(offset, length > newText.length() ? length : newText.length());
			//This is not executed while postprocessing to avoid USER Objects leak.
			currentViewer.setSelectedRange(offset, length);
		}
		if (!replacedText.equals(currentDocument.get(offset, length))) {
			throw new RuntimeException("Replaced text is not present in the document: " + this);
		}
	}

	private void postReplay() throws BadLocationException {
		if (!Configuration.isInPostprocessMode) {
			//This is not executed while postprocessing to avoid USER Objects leak.
{'fraction_non_alphanumeric': 0.09700961196155215, 'fraction_numerical': 0.0, 'mean_word_length': 5.556009334889148, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '1380060', 'n_tokens_mistral': 3490, 'n_tokens_neox': 3221, 'n_words': 736}