1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.schemaspy.view;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.TreeSet;
29 import net.sourceforge.schemaspy.DbAnalyzer;
30 import net.sourceforge.schemaspy.model.Database;
31 import net.sourceforge.schemaspy.model.ForeignKeyConstraint;
32 import net.sourceforge.schemaspy.model.Table;
33 import net.sourceforge.schemaspy.model.TableColumn;
34 import net.sourceforge.schemaspy.util.HtmlEncoder;
35 import net.sourceforge.schemaspy.util.LineWriter;
36
37
38
39
40
41
42 public class HtmlConstraintsPage extends HtmlFormatter {
43 private static HtmlConstraintsPage instance = new HtmlConstraintsPage();
44 private int columnCounter;
45
46
47
48
49 private HtmlConstraintsPage() {
50 }
51
52
53
54
55
56
57 public static HtmlConstraintsPage getInstance() {
58 return instance;
59 }
60
61 public void write(Database database, List<ForeignKeyConstraint> constraints, Collection<Table> tables, boolean hasOrphans, LineWriter html) throws IOException {
62 writeHeader(database, hasOrphans, html);
63 writeForeignKeyConstraints(constraints, html);
64 writeCheckConstraints(tables, html);
65 writeFooter(html);
66 }
67
68 private void writeHeader(Database database, boolean hasOrphans, LineWriter html) throws IOException {
69 writeHeader(database, null, "Constraints", hasOrphans, html);
70 html.writeln("<div class='indent'>");
71 }
72
73 @Override
74 protected void writeFooter(LineWriter html) throws IOException {
75 html.writeln("</div>");
76 super.writeFooter(html);
77 }
78
79
80
81
82
83
84
85
86 private void writeForeignKeyConstraints(List<ForeignKeyConstraint> constraints, LineWriter html) throws IOException {
87 Set<ForeignKeyConstraint> constraintsByName = new TreeSet<ForeignKeyConstraint>();
88 constraintsByName.addAll(constraints);
89
90 html.writeln("<table width='100%'>");
91 html.writeln("<tr><td class='container' valign='bottom'><b>");
92 html.write(String.valueOf(constraintsByName.size()));
93 html.writeln(" Foreign Key Constraints:</b>");
94 html.writeln("</td><td class='container' align='right'>");
95 html.writeln("<table>");
96 if (sourceForgeLogoEnabled())
97 html.writeln(" <tr><td class='container' align='right' valign='top'><a href='http://sourceforge.net' target='_blank'><img src='http://sourceforge.net/sflogo.php?group_id=137197&type=1' alt='SourceForge.net' border='0' height='31' width='88'></a></td></tr>");
98 html.writeln("<tr><td class='container'>");
99 writeFeedMe(html);
100 html.writeln("</td></tr></table>");
101 html.writeln("</td></tr>");
102 html.writeln("</table><br>");
103 html.writeln("<table class='dataTable' border='1' rules='groups'>");
104 html.writeln("<colgroup>");
105 html.writeln("<colgroup>");
106 html.writeln("<colgroup>");
107 html.writeln("<colgroup>");
108 html.writeln("<thead align='left'>");
109 html.writeln("<tr>");
110 html.writeln(" <th>Constraint Name</th>");
111 html.writeln(" <th>Child Column</th>");
112 html.writeln(" <th>Parent Column</th>");
113 html.writeln(" <th>Delete Rule</th>");
114 html.writeln("</tr>");
115 html.writeln("</thead>");
116 html.writeln("<tbody>");
117 for (ForeignKeyConstraint constraint : constraintsByName) {
118 writeForeignKeyConstraint(constraint, html);
119 }
120 if (constraints.size() == 0) {
121 html.writeln(" <tr>");
122 html.writeln(" <td class='detail' valign='top' colspan='4'>None detected</td>");
123 html.writeln(" </tr>");
124 }
125 html.writeln("</tbody>");
126 html.writeln("</table>");
127 }
128
129
130
131
132
133
134
135
136 private void writeForeignKeyConstraint(ForeignKeyConstraint constraint, LineWriter html) throws IOException {
137 boolean even = columnCounter++ % 2 == 0;
138 if (even)
139 html.writeln(" <tr class='even'>");
140 else
141 html.writeln(" <tr class='odd'>");
142 html.write(" <td class='detail'>");
143 html.write(constraint.getName());
144 html.writeln("</td>");
145 html.write(" <td class='detail'>");
146 for (Iterator<TableColumn> iter = constraint.getChildColumns().iterator(); iter.hasNext(); ) {
147 TableColumn column = iter.next();
148 html.write("<a href='tables/");
149 html.write(encodeHref(column.getTable().getName()));
150 html.write(".html'>");
151 html.write(column.getTable().getName());
152 html.write("</a>");
153 html.write(".");
154 html.write(column.getName());
155 if (iter.hasNext())
156 html.write("<br>");
157 }
158 html.writeln("</td>");
159 html.write(" <td class='detail'>");
160 for (Iterator<TableColumn> iter = constraint.getParentColumns().iterator(); iter.hasNext(); ) {
161 TableColumn column = iter.next();
162 html.write("<a href='tables/");
163 html.write(encodeHref(column.getTable().getName()));
164 html.write(".html'>");
165 html.write(column.getTable().getName());
166 html.write("</a>");
167 html.write(".");
168 html.write(column.getName());
169 if (iter.hasNext())
170 html.write("<br>");
171 }
172 html.writeln("</td>");
173 html.write(" <td class='detail'>");
174 String ruleText = constraint.getDeleteRuleDescription();
175 String ruleName = constraint.getDeleteRuleName();
176 html.write("<span title='" + ruleText + "'>" + ruleName + " </span>");
177 html.writeln("</td>");
178 html.writeln(" </tr>");
179 }
180
181
182
183
184
185
186
187
188 public void writeCheckConstraints(Collection<Table> tables, LineWriter html) throws IOException {
189 html.writeln("<a name='checkConstraints'></a><p>");
190 html.writeln("<b>Check Constraints:</b>");
191 html.writeln("<TABLE class='dataTable' border='1' rules='groups'>");
192 html.writeln("<colgroup>");
193 html.writeln("<colgroup>");
194 html.writeln("<colgroup>");
195 html.writeln("<thead align='left'>");
196 html.writeln("<tr>");
197 html.writeln(" <th>Table</th>");
198 html.writeln(" <th>Constraint Name</th>");
199 html.writeln(" <th>Constraint</th>");
200 html.writeln("</tr>");
201 html.writeln("</thead>");
202 html.writeln("<tbody>");
203
204 List<Table> tablesByName = DbAnalyzer.sortTablesByName(new ArrayList<Table>(tables));
205
206 int constraintsWritten = 0;
207
208
209 for (Table table : tablesByName) {
210 constraintsWritten += writeCheckConstraints(table, html);
211 }
212
213 if (constraintsWritten == 0) {
214 html.writeln(" <tr>");
215 html.writeln(" <td class='detail' valign='top' colspan='3'>None detected</td>");
216 html.writeln(" </tr>");
217 }
218
219 html.writeln("</tbody>");
220 html.writeln("</table>");
221 }
222
223
224
225
226
227
228
229
230
231 private int writeCheckConstraints(Table table, LineWriter html) throws IOException {
232 Map<String, String> constraints = table.getCheckConstraints();
233 int constraintsWritten = 0;
234 for (String name : constraints.keySet()) {
235 html.writeln(" <tr>");
236 html.write(" <td class='detail' valign='top'><a href='tables/");
237 html.write(encodeHref(table.getName()));
238 html.write(".html'>");
239 html.write(table.getName());
240 html.write("</a></td>");
241 html.write(" <td class='detail' valign='top'>");
242 html.write(name);
243 html.writeln("</td>");
244 html.write(" <td class='detail'>");
245 html.write(HtmlEncoder.encodeString(constraints.get(name).toString()));
246 html.writeln("</td>");
247 html.writeln(" </tr>");
248 ++constraintsWritten;
249 }
250
251 return constraintsWritten;
252 }
253
254 @Override
255 protected boolean isConstraintsPage() {
256 return true;
257 }
258 }