1   package com.stateofflow.eclipse.metrics.export.html;
2   
3   import java.io.IOException;
4   import java.util.Comparator;
5   
6   import com.stateofflow.eclipse.metrics.collator.MetricsCollator;
7   import com.stateofflow.eclipse.metrics.location.MetricLocation;
8   import com.stateofflow.eclipse.metrics.metric.MetricId;
9   
10  final class OrderedPageWriter {
11      private final HtmlExportFactory factory;
12      private final MetricsCollator collator;
13      private final String fileName;
14      private final String imageFileName;
15      private final String orderItem;
16      private final String level;
17      private final MetricId[] metricIds;
18      private HtmlPageBuilder pageBuilder;
19  
20      OrderedPageWriter(final HtmlExportFactory factory, final MetricsCollator collator, final String fileName, final String imageFileName, final String orderItem, final String level) {
21          this.factory = factory;
22          this.collator = collator;
23          this.fileName = fileName;
24          this.imageFileName = imageFileName;
25          this.orderItem = orderItem;
26          this.level = level;
27          metricIds = collator.getSortedMetricIds();
28      }
29  
30      public void write(final Comparator<MetricLocation> comparator) {
31          pageBuilder = factory.createHtmlPageBuilder();
32          final int[] row = new int[1];
33          final MetricsTableRowWriter rowWriter = factory.createMetricsTableRowWriter(pageBuilder);
34          collator.forEach(comparator, new MetricLocation.Closure() {;
35              public void execute(final MetricLocation location) {
36                  startNewPageIfRequired(row[0]);
37                  rowWriter.write(location, metricIds, collator);
38                  row[0]++;
39              }
40          });
41          if (row[0] > 0) {
42              closeTableFragment(collator.size() - 1);
43          }
44      }
45  
46      private void startNewPageIfRequired(final int row) {
47          if (row % getRowsPerPage() == 0) {
48              try {
49                  startTableFragment(row);
50              } catch (final IOException ioex) {
51                  throw new RuntimeException("Failed to start a table fragment: " + ioex.getMessage());
52              }
53          }
54      }
55  
56      private void startTableFragment(final int row) throws IOException {
57          if (row > 0) {
58              closeTableFragment(row - 1);
59          }
60  
61          final int fragmentNumber = getFragmentNumber(row);
62          pageBuilder.openPage(getFileNameForFragment(fragmentNumber), "Order by " + orderItem).openElement("P").printLinkAndNewline("index", "Index").openElementAndNewline("P");
63  
64          createHistogramAndAcronymListTable();
65          createTableFragmentLinks(row);
66          openMetricsTable(fragmentNumber);
67      }
68  
69      private String getFileNameForFragment(final int fragmentNumber) {
70          return fileName + "." + fragmentNumber;
71      }
72  
73      private void createHistogramAndAcronymListTable() {
74          factory.createPageHeaderWriter().write(pageBuilder, metricIds, imageFileName);
75      }
76  
77      private void closeTableFragment(final int row) {
78          pageBuilder.closeElementAndNewline("TABLE");
79          createTableFragmentLinks(row);
80          pageBuilder.closePage();
81      }
82  
83      private void createTableFragmentLinks(final int row) {
84          if (collator.size() <= getRowsPerPage()) {
85              return;
86          }
87  
88          pageBuilder.openElement("P").println("Pages:");
89          createTableFragmentPageLinks(row);
90          pageBuilder.openElementAndNewline("P");
91      }
92  
93      private void createTableFragmentPageLinks(final int row) {
94          for (int i = 1; i <= collator.size() / getRowsPerPage() + 1; i++) {
95              if (i == getFragmentNumber(row)) {
96                  pageBuilder.println(Integer.toString(i));
97              } else {
98                  pageBuilder.printLinkAndNewline(getFileNameForFragment(i), Integer.toString(i));
99              }
100         }
101     }
102 
103     private int getFragmentNumber(final int row) {
104         return row / getRowsPerPage() + 1;
105     }
106 
107     private int getRowsPerPage() {
108         return factory.getConfiguration().getRowsPerPage();
109     }
110 
111     private void openMetricsTable(final int fragmentNumber) {
112         pageBuilder.openElementAndNewline("TABLE border=\"1\" cellpadding=\"2\"").openElement("TR");
113         factory.createMetricsTableHeaderWriter().write(pageBuilder, fragmentNumber, level, metricIds, collator);
114         pageBuilder.closeElementAndNewline("TR");
115     }
116 }
117