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