View Javadoc

1   package org.kuali.maven.mojo.s3;
2   
3   import java.text.SimpleDateFormat;
4   import java.util.ArrayList;
5   import java.util.Collection;
6   import java.util.Date;
7   import java.util.List;
8   
9   /**
10   * Generate directory listings in html format that is Amazon CloudFront friendly
11   */
12  public class CloudFrontHtmlGenerator {
13  	HtmlUtils html = new HtmlUtils();
14  	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
15  
16  	S3BucketContext context;
17  
18  	public CloudFrontHtmlGenerator() {
19  		this(null);
20  	}
21  
22  	public CloudFrontHtmlGenerator(final S3BucketContext context) {
23  		super();
24  		this.context = context;
25  	}
26  
27  	/**
28  	 * Decorators for the columns in the table
29  	 */
30  	protected List<ColumnDecorator> getColumnDecorators() {
31  		List<ColumnDecorator> columnDecorators = new ArrayList<ColumnDecorator>();
32  		columnDecorators.add(new ColumnDecorator("image-column", "sort-header", ""));
33  		columnDecorators.add(new ColumnDecorator("name-column", "sort-header", "Name"));
34  		columnDecorators.add(new ColumnDecorator("last-modified-column", "sort-header", "Last Modified"));
35  		columnDecorators.add(new ColumnDecorator("size-column", "sort-header", "Size"));
36  		return columnDecorators;
37  	}
38  
39  	/**
40  	 * If prefix is null, return the delimiter.<br>
41  	 * If delimiter is "/" and prefix is "foo/bar" return "/foo/bar"<br>
42  	 * If delimiter is "/" and prefix is "foo/bar/" return "/foo/bar"
43  	 */
44  	protected String getDirectory(final String prefix, final String delimiter) {
45  		if (prefix == null) {
46  			return delimiter;
47  		}
48  		if (prefix.endsWith(delimiter)) {
49  			return delimiter + prefix.substring(0, prefix.length() - delimiter.length());
50  		} else {
51  			return delimiter + prefix;
52  		}
53  	}
54  
55  	protected String getHtmlComment() {
56  		return "<!-- Generated on " + sdf.format(new Date()) + " -->\n";
57  	}
58  
59  	protected String getDocType() {
60  		return "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
61  	}
62  
63  	protected String getMeta() {
64  		return "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>\n";
65  	}
66  
67  	protected String getGoogleAnalyticsJavascript() {
68  		return "<script type=\"text/javascript\">var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-16781661-1']); _gaq.push(['_setDomainName', '.kuali.org']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();</script>\n";
69  	}
70  
71  	/**
72  	 * Generate the full html page
73  	 */
74  	public String getHtml(final List<String[]> data, final String prefix, final String delimiter) {
75  		String directory = getDirectory(prefix, delimiter);
76  
77  		Tag html = new Tag("html");
78  		Tag title = new Tag("title");
79  		Tag head = new Tag("head");
80  		Tag body = new Tag("body");
81  		Tag div1 = new Tag("div", "title");
82  		Tag span1 = new Tag("span", null, "title");
83  		Tag div2 = new Tag("div", "data");
84  		Tag div3 = new Tag("div", "footer", "footer-left");
85  		Tag span2 = new Tag("span", null, "footer-text");
86  
87  		StringBuffer sb = new StringBuffer();
88  		sb.append(getDocType());
89  		sb.append(this.html.openTag(html));
90  		sb.append(this.html.getIndentedContent(getHtmlComment()));
91  		sb.append(this.html.getTag(title, "Directory listing for " + directory));
92  		sb.append(this.html.openTag(head));
93  		sb.append(this.html.getIndentedContent("<link href=\"" + context.getCss()
94  				+ "\" rel=\"stylesheet\" type=\"text/css\"/>\n"));
95  		sb.append(this.html.getIndentedContent(getMeta()));
96  		sb.append(this.html.getIndentedContent(getGoogleAnalyticsJavascript()));
97  		sb.append(this.html.closeTag(head));
98  		sb.append(this.html.openTag(body));
99  		sb.append(this.html.openTag(div1));
100 		sb.append(this.html.getTag(span1, "Directory listing for " + directory));
101 		sb.append(this.html.closeTag(div1));
102 		sb.append(this.html.getIndentedContent("<hr>\n"));
103 		sb.append(this.html.openTag(div2));
104 		sb.append(getHtmlTable(data, getColumnDecorators()));
105 		sb.append(this.html.closeTag(div2));
106 		sb.append(this.html.getIndentedContent("<hr>\n"));
107 		sb.append(this.html.openTag(div3));
108 		sb.append(this.html.getTag(span2, context.getAbout()));
109 		sb.append(this.html.closeTag(div3));
110 		sb.append(this.html.closeTag(body));
111 		sb.append(this.html.closeTag(html));
112 		return sb.toString();
113 	}
114 
115 	/**
116 	 * Generate html representing the contents of one table cell
117 	 */
118 	protected String getTableCell(final String content, final ColumnDecorator decorator) {
119 		Tag td = new Tag("td", decorator.getTableDataClass());
120 		return html.getTag(td, content);
121 	}
122 
123 	/**
124 	 * Return true if the Collection is null or contains no entries, false otherwise
125 	 */
126 	protected boolean isEmpty(final Collection<?> c) {
127 		return c == null || c.size() == 0;
128 	}
129 
130 	/**
131 	 * Alternate the styling of each row
132 	 */
133 	protected Tag getTableRowTag(final int row) {
134 		if ((row % 2) == 0) {
135 			return new Tag("tr", "table-tr-odd");
136 		} else {
137 			return new Tag("tr");
138 		}
139 	}
140 
141 	/**
142 	 * Generate an html table row for the String[]
143 	 */
144 	protected String getTableRow(final int row, final String[] data, final List<ColumnDecorator> columnDecorators) {
145 		StringBuffer sb = new StringBuffer();
146 		Tag tr = getTableRowTag(row);
147 		sb.append(html.openTag(tr));
148 		for (int i = 0; i < data.length; i++) {
149 			sb.append(getTableCell(data[i], columnDecorators.get(i)));
150 		}
151 		sb.append(html.closeTag(tr));
152 		return sb.toString();
153 	}
154 
155 	/**
156 	 * Generate a table row for each String[] in the list
157 	 */
158 	protected String getTableRows(final List<String[]> data, final List<ColumnDecorator> columnDecorators) {
159 		StringBuffer sb = new StringBuffer();
160 		for (int i = 0; i < data.size(); i++) {
161 			sb.append(getTableRow(i, data.get(i), columnDecorators));
162 		}
163 		return sb.toString();
164 	}
165 
166 	/**
167 	 * Generate the html for the th tags from a list of ColumnDecorator objects
168 	 */
169 	protected String getTableHeaders(final List<ColumnDecorator> columnDecorators) {
170 		StringBuffer sb = new StringBuffer();
171 		for (int i = 0; i < columnDecorators.size(); i++) {
172 			ColumnDecorator decorator = columnDecorators.get(i);
173 			Tag th = new Tag("th", decorator.getTableDataClass());
174 			sb.append(html.openTag(th));
175 			sb.append(html.getTag(new Tag("span", decorator.getSpanClass()), decorator.getColumnTitle()));
176 			sb.append(html.closeTag(th));
177 		}
178 		return sb.toString();
179 	}
180 
181 	/**
182 	 * Generate the table representing a directory listing
183 	 */
184 	protected String getHtmlTable(final List<String[]> data, final List<ColumnDecorator> columnDecorators) {
185 		if (isEmpty(data)) {
186 			return "";
187 		}
188 		StringBuffer sb = new StringBuffer();
189 		Tag table = new Tag("table", "mainTable");
190 		Tag thead = new Tag("thead");
191 		Tag tr = new Tag("tr");
192 		Tag tbody = new Tag("tbody");
193 		sb.append(html.openTag(table));
194 		sb.append(html.openTag(thead));
195 		sb.append(html.openTag(tr));
196 		sb.append(getTableHeaders(columnDecorators));
197 		sb.append(html.closeTag(tr));
198 		sb.append(html.closeTag(thead));
199 		sb.append(html.openTag(tbody));
200 		sb.append(getTableRows(data, columnDecorators));
201 		sb.append(html.closeTag(tbody));
202 		sb.append(html.closeTag(table));
203 		return sb.toString();
204 	}
205 
206 	public S3BucketContext getContext() {
207 		return context;
208 	}
209 
210 	public void setContext(final S3BucketContext context) {
211 		this.context = context;
212 	}
213 
214 }