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.collections4.sequence; 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 SequencesComparator SequencesComparator} 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 * @param <T> the type of object to apply commands. 41 * @see SequencesComparator 42 * @see EditCommand 43 * @see CommandVisitor 44 * @see ReplacementsHandler 45 * @since 4.0 46 */ 47 public class EditScript<T> { 48 49 /** Container for the commands. */ 50 private final List<EditCommand<T>> commands; 51 52 /** Length of the longest common subsequence. */ 53 private int lcsLength; 54 55 /** Number of modifications. */ 56 private int modifications; 57 58 /** 59 * Simple constructor. Creates a new empty script. 60 */ 61 public EditScript() { 62 commands = new ArrayList<>(); 63 lcsLength = 0; 64 modifications = 0; 65 } 66 67 /** 68 * Add a delete command to the script. 69 * 70 * @param command command to add 71 */ 72 public void append(final DeleteCommand<T> command) { 73 commands.add(command); 74 ++modifications; 75 } 76 77 /** 78 * Add an insert command to the script. 79 * 80 * @param command command to add 81 */ 82 public void append(final InsertCommand<T> command) { 83 commands.add(command); 84 ++modifications; 85 } 86 87 /** 88 * Add a keep command to the script. 89 * 90 * @param command command to add 91 */ 92 public void append(final KeepCommand<T> command) { 93 commands.add(command); 94 ++lcsLength; 95 } 96 97 /** 98 * Gets the length of the Longest Common Subsequence (LCS). The length of the 99 * longest common subsequence is the number of {@link KeepCommand keep 100 * commands} in the script. 101 * 102 * @return length of the Longest Common Subsequence 103 */ 104 public int getLCSLength() { 105 return lcsLength; 106 } 107 108 /** 109 * Gets the number of effective modifications. The number of effective 110 * modification is the number of {@link DeleteCommand delete} and 111 * {@link InsertCommand insert} commands in the script. 112 * 113 * @return number of effective modifications 114 */ 115 public int getModifications() { 116 return modifications; 117 } 118 119 /** 120 * Visit the script. The script implements the <em>visitor</em> design 121 * pattern, this method is the entry point to which the user supplies its 122 * own visitor, the script will be responsible to drive it through the 123 * commands in order and call the appropriate method as each command is 124 * encountered. 125 * 126 * @param visitor the visitor that will visit all commands in turn 127 */ 128 public void visit(final CommandVisitor<T> visitor) { 129 for (final EditCommand<T> command : commands) { 130 command.accept(visitor); 131 } 132 } 133 134 }