View Javadoc

1   package net.sf.appstatus.web;
2   
3   import static java.text.DateFormat.getDateTimeInstance;
4   import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
5   import static org.apache.commons.lang3.StringEscapeUtils.escapeJson;
6   
7   import java.io.IOException;
8   import java.io.InputStream;
9   import java.io.StringWriter;
10  import java.io.UnsupportedEncodingException;
11  import java.nio.charset.Charset;
12  import java.text.DateFormat;
13  import java.util.Collection;
14  import java.util.Date;
15  import java.util.HashMap;
16  import java.util.Iterator;
17  import java.util.List;
18  import java.util.Map;
19  
20  import org.apache.commons.io.IOUtils;
21  import org.apache.commons.lang3.text.StrBuilder;
22  import org.apache.commons.lang3.text.StrSubstitutor;
23  
24  import net.sf.appstatus.web.pages.Resources;
25  
26  /**
27   * Support class for generating Html tables.
28   *
29   * @author Nicolas
30   *
31   */
32  public class HtmlUtils {
33  	private static final String ENCODING = "UTF-8";
34  	private static Map<String, String> templates = new HashMap<String, String>();
35  
36  	public static String applyLayout(Map<String, String> valuesMap, String templateName) throws IOException {
37  		String templateString = "";
38  
39  		if (templates.containsKey(templateName)) {
40  			templateString = templates.get(templateName);
41  		} else {
42  			// get the file
43  			InputStream inputStream = Resources.class.getResourceAsStream("/templates/" + templateName);
44  
45  			// convert to string
46  			StringWriter writer = new StringWriter();
47  			IOUtils.copy(inputStream, writer, Charset.defaultCharset());
48  			templateString = writer.toString();
49  			templates.put(templateName, templateString);
50  		}
51  
52  		// substitution & return
53  		StrSubstitutor sub = new StrSubstitutor(valuesMap);
54  		return sub.replace(templateString);
55  	}
56  
57  	public static String collectionToDelimitedString(Collection coll, String delim, String prefix, String suffix) {
58  		if (isEmpty(coll)) {
59  			return "";
60  		}
61  		StringBuilder sb = new StringBuilder();
62  		Iterator it = coll.iterator();
63  		while (it.hasNext()) {
64  			sb.append(prefix).append(it.next()).append(suffix);
65  			if (it.hasNext()) {
66  				sb.append(delim);
67  			}
68  		}
69  		return sb.toString();
70  	}
71  
72  	public static String countAndDetail(List<String> items) {
73  		String itemsList = collectionToDelimitedString(items, ", ", "", "");
74  		return "<a href='#' title='" + escapeHtml4(itemsList) + "'>" + items.size() + "</a>"
75  				+ "<span style=\"display:none\" >" + itemsList + "</span>";
76  	}
77  
78  	/**
79  	 * Prints table start tag, or a message if table is empty.
80  	 *
81  	 * @param size
82  	 * @return true if we can go on with table generation.
83  	 * @throws IOException
84  	 * @throws UnsupportedEncodingException
85  	 */
86  	public static boolean generateBeginTable(StrBuilder sb, int size) throws UnsupportedEncodingException, IOException {
87  		if (size == 0) {
88  			sb.append("<p>No items</p>");
89  			return false;
90  		}
91  
92  		sb.append("<table class=\"table table-hover table-condensed\">");
93  		return true;
94  	}
95  
96  	public static void generateEndTable(StrBuilder sb, int size) throws UnsupportedEncodingException, IOException {
97  
98  		if (size > 0) {
99  			sb.append("</tbody></table>");
100 		}
101 	}
102 
103 	/**
104 	 * Outputs table headers.
105 	 *
106 	 * <p>
107 	 * <b>WARNING</b> : this method accepts HTML content as table headers. Any
108 	 * sensitive value must be encoded before calling this method.
109 	 *
110 	 * @param sb
111 	 *            The target string builder.
112 	 * @param cols
113 	 *            Column titles (HTML).
114 	 */
115 	public static void generateHeaders(StrBuilder sb, Object... cols) {
116 		sb.append("<thead><tr>");
117 		for (Object obj : cols) {
118 			sb.append("<th>");
119 			if (obj != null) {
120 
121 				if (obj instanceof Long) {
122 					sb.append(((Long) obj).longValue());
123 				} else {
124 					sb.append(obj.toString());
125 				}
126 			}
127 			sb.append("</th>");
128 		}
129 		sb.append("</tr></thead><tbody>");
130 	}
131 
132 	/**
133 	 * Outputs one table row.
134 	 * <p>
135 	 * <b>WARNING</b> : this method accepts HTML content as row content. Any
136 	 * sensitive value must be encoded before calling this method.
137 	 *
138 	 *
139 	 * @param sb
140 	 *            The target string builder.
141 	 * @param status
142 	 *            status class name.
143 	 * @param cols
144 	 *            Column titles (HTML).
145 	 * @throws IOException
146 	 */
147 	public static void generateRow(StrBuilder sb, String status, Object... cols) throws IOException {
148 		sb.append("<tr>");
149 
150 		sb.append(("<td class='icon'><img src='?icon=" + escapeHtml4(status) + "'></td>"));
151 
152 		for (Object obj : cols) {
153 			sb.append("<td>");
154 			if (obj != null) {
155 
156 				if (obj instanceof Date) {
157 					DateFormat dateFormat = getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
158 					sb.append(dateFormat.format((Date) obj));
159 				} else {
160 					sb.append(obj.toString());
161 				}
162 			}
163 			sb.append("</td>");
164 
165 		}
166 		sb.append("</tr>");
167 	}
168 
169 	/**
170 	 * Null-safe empty test for Collections.
171 	 *
172 	 * @param collection
173 	 * @return
174 	 */
175 	public static boolean isEmpty(Collection<?> collection) {
176 		return (collection == null || collection.isEmpty());
177 	}
178 
179 	public static String json(String name, Object o) {
180 		String result = "\"" + escapeJson(name) + "\" :";
181 
182 		if (o == null) {
183 			result = result + "null";
184 		} else if (o instanceof String) {
185 			result = result + "\"" + escapeJson((String) o) + "\"";
186 		} else if (o instanceof Integer) {
187 			result = result + ((Integer) o).intValue();
188 		} else if (o instanceof Double) {
189 			result = result + ((Double) o).doubleValue();
190 		} else if (o instanceof Long) {
191 			result = result + ((Long) o).longValue();
192 		}
193 
194 		return result + "\n";
195 	}
196 }