All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.epsilon.egl.patch.Patch Maven / Gradle / Ivy

/*********************************************************************
* Copyright (c) 2008 The University of York.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/
package org.eclipse.epsilon.egl.patch;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 
 * @since 1.6
 */
public class Patch extends TextBlock {
	
	public Patch() {}
	
	public Patch(String... lines) {
		LineFactory lineFactory = new LineFactory();
		for (int i=0; i validate() {
		List diagnostics = new ArrayList<>();
		
		for (Line line : lines) {
			if (line.is(LineType.KEEP_WILDCARD)) {
				if (isFirstLine(line)) {
					diagnostics.add(new PatchValidationDiagnostic(line, "Wildcards are not allowed at the beginning of a patch"));
				}
				else if (isLastLine(line)) {
					diagnostics.add(new PatchValidationDiagnostic(line, "Wildcards are not allowed at the end of a patch"));					
				}
				
				if (!isFirstLine(line) && getPreviousLine(line).is(LineType.KEEP_WILDCARD)) {
					diagnostics.add(new PatchValidationDiagnostic(line, "Consecutive wildcards are not allowed"));					
				}
				if (!isLastLine(line) && getNextLine(line).is(LineType.KEEP_WILDCARD)) {
					diagnostics.add(new PatchValidationDiagnostic(line, "Consecutive wildcards are not allowed"));
				}
			}
		}
		
		return diagnostics;
	}
	
	public boolean isValid() {
		return validate().isEmpty();
	}
	
	public List match(TextBlock block) {
				
		Line startMatchBlockLine = null;
		List matches = new ArrayList<>();
		Patch keepsAndRemoves = this.keepsAndRemoves();
		
		if (keepsAndRemoves.getLines().isEmpty()) return matches;
		
		LineMap lineMap = new LineMap();
		Line blockLine = block.getFirstLine();
		Line patchLine = keepsAndRemoves.getFirstLine();
		
		while (blockLine != null) {
			
			if (patchLine.is(LineType.KEEP_WILDCARD) || patchLine.is(LineType.REMOVE_WILDCARD)) {
				Line matchLine = keepsAndRemoves.getNextLine(patchLine);
				
				if (matchLine == null) {
					if (startMatchBlockLine != null) {
						while (blockLine != null) {
							lineMap.put(patchLine, blockLine);
							blockLine = block.getNextLine(blockLine);
						}
						matches.add(new Match(block, startMatchBlockLine, block.getLastLine(), this, lineMap));
					}
					break;
				}
				else {
					if (startMatchBlockLine == null) startMatchBlockLine = blockLine;
					
					while (blockLine != null && !matchLine.getTrimmedText().contentEquals(blockLine.getTrimmedText())) {
						lineMap.put(patchLine, blockLine);
						blockLine = block.getNextLine(blockLine);
					}
					
					patchLine = matchLine;
					continue;
				}
			}
			else if (patchLine.getTrimmedText().contentEquals(blockLine.getTrimmedText())) {
				lineMap.put(patchLine, blockLine);
				if (startMatchBlockLine == null) {
					startMatchBlockLine = blockLine;
				}
				
				if (keepsAndRemoves.isLastLine(patchLine)) {
					matches.add(new Match(block, startMatchBlockLine, blockLine, this, lineMap));
					patchLine = keepsAndRemoves.getFirstLine();
					startMatchBlockLine = null;
					lineMap = new LineMap();
				}
				else {
					patchLine = keepsAndRemoves.getNextLine(patchLine);
				}
				blockLine = block.getNextLine(blockLine);
			}
			else {
				blockLine = block.getNextLine(blockLine);
				patchLine = keepsAndRemoves.getFirstLine();
				startMatchBlockLine = null;
				lineMap = new LineMap();
			}
			
		}
		
		return matches;
	}
	
	public boolean appliesTo(TextBlock block) {
		return match(block).size() > 0;
	}
	
	public TextBlock apply(TextBlock block) {
		List matches = match(block);
		if (matches.isEmpty()) return block;
		
		TextBlock merged = new TextBlock();
		Iterator matchIterator = matches.iterator();
		Match match = matchIterator.next();
		
		Line originalLine = block.getFirstLine();
		
		while (originalLine != null) {
			if (match != null && originalLine == match.getStartLine()) {
				for (Line patchLine : match.getPatch().getLines()) {
					if (patchLine.is(LineType.COMMENT)) {}
					else if (patchLine.is(LineType.KEEP_WILDCARD)) {
						for (Line blockLine : match.getLineMap().get(patchLine)) {
							merged.getLines().add(blockLine);
						}
					}
					else if (patchLine.is(LineType.REMOVE_WILDCARD)) {}
					else if (patchLine.isNot(LineType.REMOVE)) {
						String text;
						if (patchLine.is(LineType.INSERT)) text = patchLine.getText();
						else text = match.getLineMap().get(patchLine).get(0).getText();
						merged.getLines().add(new Line(LineType.REGULAR, text, -1));
					}
				}
				
				originalLine = block.getNextLine(match.getEndLine());
				if (matchIterator.hasNext()) match = matchIterator.next();
				else match = null;
			}
			else {
				merged.getLines().add(originalLine);
				originalLine = block.getNextLine(originalLine);
			}
		}
		
		return merged;
	}
	
	public Patch keepsAndRemoves() {
		Patch patch = new Patch();
		patch.getLines().addAll(this.getLines().stream().
				filter(l -> l.getType() == LineType.REGULAR 
						 || l.getType() == LineType.REMOVE
						 || l.getType() == LineType.KEEP_WILDCARD
						 || l.getType() == LineType.REMOVE_WILDCARD).
				collect(Collectors.toList()));
		return patch;
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy