1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.text.diff; 18 19 import java.util.ArrayList; 20 import java.util.List; 21 22 /** 23 * This class gathers all the {@link EditCommand commands} needed to transform 24 * one objects sequence into another objects sequence. 25 * <p> 26 * An edit script is the most general view of the differences between two 27 * sequences. It is built as the result of the comparison between two sequences 28 * by the {@link StringsComparator StringsComparator} class. The user can 29 * walk through it using the <em>visitor</em> design pattern. 30 * </p> 31 * <p> 32 * It is guaranteed that the objects embedded in the {@link InsertCommand insert 33 * commands} come from the second sequence and that the objects embedded in 34 * either the {@link DeleteCommand delete commands} or {@link KeepCommand keep 35 * commands} come from the first sequence. This can be important if subclassing 36 * is used for some elements in the first sequence and the {@code equals} 37 * method is specialized. 38 * </p> 39 * 40 * @see StringsComparator 41 * @see EditCommand 42 * @see CommandVisitor 43 * @see ReplacementsHandler 44 * 45 * @param <T> object type 46 * @since 1.0 47 */ 48 public class EditScript<T> { 49 50 /** Container for the commands. */ 51 private final List<EditCommand<T>> commands; 52 53 /** Length of the longest common subsequence. */ 54 private int lcsLength; 55 56 /** Number of modifications. */ 57 private int modifications; 58 59 /** 60 * Constructs a new empty script. 61 */ 62 public EditScript() { 63 commands = new ArrayList<>(); 64 lcsLength = 0; 65 modifications = 0; 66 } 67 68 /** 69 * Appends a delete command to the script. 70 * 71 * @param command command to add 72 */ 73 public void append(final DeleteCommand<T> command) { 74 commands.add(command); 75 ++modifications; 76 } 77 78 /** 79 * Appends an insert command to the script. 80 * 81 * @param command command to add 82 */ 83 public void append(final InsertCommand<T> command) { 84 commands.add(command); 85 ++modifications; 86 } 87 88 /** 89 * Appends a keep command to the script. 90 * 91 * @param command command to add 92 */ 93 public void append(final KeepCommand<T> command) { 94 commands.add(command); 95 ++lcsLength; 96 } 97 98 /** 99 * Gets the length of the Longest Common Subsequence (LCS). The length of the 100 * longest common subsequence is the number of {@link KeepCommand keep 101 * commands} in the script. 102 * 103 * @return length of the Longest Common Subsequence 104 */ 105 public int getLCSLength() { 106 return lcsLength; 107 } 108 109 /** 110 * Gets the number of effective modifications. The number of effective 111 * modification is the number of {@link DeleteCommand delete} and 112 * {@link InsertCommand insert} commands in the script. 113 * 114 * @return number of effective modifications 115 */ 116 public int getModifications() { 117 return modifications; 118 } 119 120 /** 121 * Visits the script. The script implements the <em>visitor</em> design 122 * pattern, this method is the entry point to which the user supplies its 123 * own visitor, the script will be responsible to drive it through the 124 * commands in order and call the appropriate method as each command is 125 * encountered. 126 * 127 * @param visitor the visitor that will visit all commands in turn 128 */ 129 public void visit(final CommandVisitor<T> visitor) { 130 commands.forEach(command -> command.accept(visitor)); 131 } 132 133 }