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 }