View Javadoc
1   /*
2    *    Copyright 2010-2022 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.mybatis.maven.mvnmigrate.report;
17  
18  import java.util.List;
19  import java.util.Map;
20  import java.util.Map.Entry;
21  import java.util.ResourceBundle;
22  
23  import org.apache.ibatis.migration.Change;
24  import org.apache.maven.doxia.sink.Sink;
25  import org.apache.maven.project.MavenProject;
26  
27  /**
28   * View of status report.
29   */
30  public final class MigrationStatusReportView {
31  
32    /**
33     * Generates the report.
34     *
35     * @param changes
36     *          list of {@link Change}
37     * @param sink
38     *          the {@link Sink} instance
39     * @param bundle
40     *          the {@link ResourceBundle} instance
41     */
42    public void generateReport(Map<MavenProject, List<Change>> changes, Sink sink, ResourceBundle bundle,
43        boolean isAggregate) {
44  
45      sink.head();
46      sink.title();
47      sink.text(bundle.getString("migration.status.report.header"));
48      sink.title_();
49      sink.head_();
50      sink.body();
51  
52      // Generate title
53      sink.section1();
54      sink.sectionTitle1();
55      sink.text(bundle.getString("migration.status.report.mainTitle"));
56      sink.sectionTitle1_();
57      sink.section1_();
58      sink.lineBreak();
59  
60      sink.section2();
61      sink.sectionTitle2();
62      sink.text(bundle.getString("migration.status.report.secondSectionTitle"));
63      sink.sectionTitle2_();
64  
65      for (Entry<MavenProject, List<Change>> entries : changes.entrySet()) {
66        if (isAggregate) {
67          sink.section3();
68          sink.sectionTitle3();
69          sink.text(bundle.getString("migration.status.report.moduleTitle") + entries.getKey().getName());
70          sink.sectionTitle3_();
71        }
72        generateStatisticsTable(sink, entries.getValue());
73      }
74  
75      sink.section2_();
76      sink.lineBreak();
77  
78      sink.section3();
79      sink.sectionTitle2();
80      sink.text(bundle.getString("migration.status.report.thirdSectionTitle"));
81      sink.sectionTitle2_();
82      for (Entry<MavenProject, List<Change>> entries : changes.entrySet()) {
83        if (isAggregate) {
84          sink.section3();
85          sink.sectionTitle3();
86          sink.text(bundle.getString("migration.status.report.moduleTitle") + entries.getKey().getName());
87          sink.sectionTitle3_();
88        }
89        // Generate Unused declared dependencies:
90        generateChangesTable(sink, entries.getValue());
91      }
92  
93      sink.section3_();
94  
95      // Closing the report
96      sink.body_();
97      sink.flush();
98      sink.close();
99    }
100 
101   /**
102    * Generates statistic table.
103    *
104    * @param sink
105    *          the sink
106    * @param changes
107    *          the changes
108    */
109   private void generateStatisticsTable(Sink sink, List<Change> changes) {
110     sink.table();
111 
112     sink.tableRow();
113     sink.tableCell();
114     sink.text(" Number of migration changes: ");
115     sink.tableCell_();
116 
117     sink.tableCell();
118     sink.text("" + changes.size());
119     sink.tableCell_();
120     sink.tableRow_();
121 
122     sink.tableRow();
123     sink.tableCell();
124     sink.text(" Number of pending migrations: ");
125     sink.tableCell_();
126 
127     int nop = numberOfPending(changes);
128 
129     sink.tableCell();
130     sink.text(nop + "  (" + calcPerc(changes.size(), nop) + ")  ");
131     sink.nonBreakingSpace();
132     sink.figure();
133     sink.figureGraphics(nop == 0 ? "images/icon_success_sml.gif" : "images/icon_warning_sml.gif");
134     sink.figure_();
135     sink.tableCell_();
136     sink.tableRow_();
137 
138     sink.table_();
139   }
140 
141   /**
142    * Calculates the percentage.
143    *
144    * @param tot
145    *          the tot
146    * @param nop
147    *          the nop
148    *
149    * @return the string
150    */
151   private String calcPerc(int tot, int nop) {
152     return "" + ((100 * nop) / tot) + "%";
153   }
154 
155   /**
156    * Return the number of pending change found.
157    *
158    * @param changes
159    *          list of {@link Change}
160    *
161    * @return Return the number of pending change found.
162    */
163   private int numberOfPending(List<Change> changes) {
164     int numberOfPending = 0;
165     for (Change change : changes) {
166       if (change.getAppliedTimestamp() == null) {
167         numberOfPending++;
168       }
169     }
170     return numberOfPending;
171   }
172 
173   /**
174    * Generate a table for the given dependencies iterator.
175    *
176    * @param sink
177    *          the {@link Sink} instance
178    * @param iter
179    *          list of {@link Change}
180    */
181   public void generateChangesTable(Sink sink, List<Change> iter) {
182     sink.table();
183 
184     sink.tableRow();
185     sink.tableCell();
186     sink.bold();
187     sink.text("ID");
188     sink.bold_();
189     sink.tableCell_();
190 
191     sink.tableCell();
192     sink.bold();
193     sink.text("Applied At");
194     sink.bold_();
195     sink.tableCell_();
196 
197     sink.tableCell();
198     sink.bold();
199     sink.text("Description");
200     sink.bold_();
201     sink.tableCell_();
202 
203     sink.tableCell();
204     sink.bold();
205     sink.text("Filename");
206     sink.bold_();
207     sink.tableCell_();
208 
209     sink.tableCell();
210     sink.bold();
211     sink.text("Status");
212     sink.bold_();
213     sink.tableCell_();
214 
215     sink.tableRow_();
216 
217     for (Change change : iter) {
218       sink.tableRow();
219 
220       sink.tableCell();
221       sink.text("" + change.getId());
222       sink.tableCell_();
223 
224       sink.tableCell();
225       sink.text(change.getAppliedTimestamp() == null ? " ... pending ... " : change.getAppliedTimestamp());
226       sink.tableCell_();
227 
228       sink.tableCell();
229       sink.text(change.getDescription());
230       sink.tableCell_();
231 
232       sink.tableCell();
233       sink.text(change.getFilename());
234       sink.tableCell_();
235 
236       sink.tableCell();
237       sink.figure();
238       sink.figureGraphics(
239           change.getAppliedTimestamp() != null ? "images/icon_success_sml.gif" : "images/icon_warning_sml.gif");
240       sink.figure_();
241       sink.tableCell_();
242 
243       sink.tableRow_();
244     }
245 
246     sink.table_();
247     sink.horizontalRule();
248   }
249 
250 }