1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package de.smartics.properties.admin.resources.representation.html.share;
17
18 import static de.smartics.resteasy.hypermedia.relations.Relations.HOME;
19 import static de.smartics.resteasy.hypermedia.relations.Relations.SELF;
20 import static de.smartics.resteasy.hypermedia.relations.Relations.UP;
21
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.net.URI;
25 import java.security.Principal;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import javax.ws.rs.core.UriBuilder;
30
31 import org.apache.commons.lang.StringUtils;
32
33 import de.smartics.html5.jatl.Html;
34 import de.smartics.html5.jatl.HtmlFactory;
35 import de.smartics.html5.jatl.HtmlResourceContext;
36 import de.smartics.properties.admin.resources.controller.ApiResource;
37 import de.smartics.properties.admin.resources.representation.share.AbstractRepresentationRenderer;
38 import de.smartics.resteasy.hypermedia.renderer.LinkDescriptor;
39 import de.smartics.resteasy.hypermedia.resources.Resources;
40
41
42
43
44
45
46
47 public abstract class AbstractHtmlRepresentationRenderer<T> extends
48 AbstractRepresentationRenderer<T>
49 {
50
51
52
53
54
55
56
57
58
59 protected final HtmlResourceContext htmlContext;
60
61
62
63
64 protected final HtmlFactory factory;
65
66
67
68
69 protected final Html html;
70
71
72
73
74 protected final HtmlPathHelper pathHelper;
75
76
77
78
79
80
81
82
83
84
85
86 protected AbstractHtmlRepresentationRenderer(
87 final HtmlResourceContext htmlContext, final OutputStream entityStream)
88 {
89 super(htmlContext.getContext(), htmlContext.getFactory().getCharset()
90 .displayName(), entityStream, "getAsHtml");
91
92 this.htmlContext = htmlContext;
93 this.factory = htmlContext.getFactory();
94 this.html = factory.create(entityStream);
95 this.pathHelper = new HtmlPathHelper(htmlContext.getContext().getUriInfo());
96 }
97
98
99
100
101
102
103
104
105
106
107
108 @Override
109 protected final void httpBody()
110 {
111 html.declaration();
112 html.html();
113
114 htmlHead();
115 htmlBody();
116
117 html.end();
118 }
119
120 private void htmlHead()
121 {
122 html.head();
123 html.title().text(getTitle()).end();
124 html.meta().attr("charset", factory.getCharset().toString()).end();
125
126 final String bootstrapCssUrl = pathHelper.bootstrap("css/bootstrap.css");
127 html.link().rel("stylesheet").type("text/css").href(bootstrapCssUrl)
128 .media("screen").end();
129
130 final String cssUrl = pathHelper.css("properties.css");
131 html.link().rel("stylesheet").type("text/css").href(cssUrl).media("screen")
132 .end();
133
134 renderApplicationStateHtmlHead();
135
136 html.end();
137 }
138
139 private void renderApplicationStateHtmlHead()
140 {
141 final Resources discovery = htmlContext.getContext().getDiscovery();
142 for (final LinkDescriptor link : discovery.links())
143 {
144 final String rel = link.getRel();
145 final String href = link.getHref();
146
147 html.link().rel(rel);
148
149 final String type = link.getType();
150 if (StringUtils.isNotBlank(type))
151 {
152 html.type(type);
153 }
154 html.href(href);
155
156 html.end();
157 }
158 }
159
160
161
162
163
164
165 protected abstract String getTitle();
166
167
168
169
170
171
172 protected void renderPageTitle(final String subTitle)
173 {
174 html.div().classAttr("page-header");
175
176 html.h1().text(getTitle());
177 if (StringUtils.isNotBlank(subTitle))
178 {
179 html.text(" ").small().text(subTitle).end();
180 }
181 html.end();
182
183 html.end();
184 }
185
186 private void htmlBody()
187 {
188 html.body();
189 html.script().src(pathHelper.jquery("jquery.js")).end();
190 html.script().src(pathHelper.bootstrap("js/bootstrap.js")).end();
191
192 html.div().id("wrap");
193 controls();
194 breadcrumbs();
195 html.div().classAttr("container");
196 bodyContents();
197 html.end();
198 html.end();
199
200 footer();
201 html.end();
202 }
203
204 private void controls()
205 {
206 html.div().classAttr("pull-right");
207 html.div().classAttr("btn-group");
208
209 renderLogout();
210
211 html.end();
212 html.end();
213 }
214
215 private void renderLogout()
216 {
217 final UriBuilder builder =
218 htmlContext.getContext().getUriInfo().getBaseUriBuilder();
219 final URI uri = builder.path(ApiResource.class, "logout").build();
220 final String logoutUrl = uri.toString();
221 html.form().classAttr("form-inline").method("POST").action(logoutUrl);
222
223 html.button().type("submit").id("logout")
224 .classAttr("btn btn-mini btn-default");
225 final String user = calcUser();
226 html.text("logout " + user).end();
227
228 html.end();
229 }
230
231 private String calcUser()
232 {
233 final Principal principal =
234 htmlContext.getContext().getRequest().getUserPrincipal();
235 if (principal != null)
236 {
237 return principal.getName();
238 }
239 else
240 {
241 return "";
242 }
243 }
244
245
246
247
248
249
250 protected abstract List<LinkDescriptor> breadcrumbLinks();
251
252 private void breadcrumbs()
253 {
254 final List<LinkDescriptor> breadcrumbs = breadcrumbLinks();
255 if (breadcrumbs.isEmpty())
256 {
257 return;
258 }
259
260 final int size = breadcrumbs.size();
261 if (size == 0)
262 {
263 return;
264 }
265
266 html.start("nav").ul().classAttr("breadcrumb");
267 final List<String> ups = new ArrayList<String>();
268 for (int i = 0; i < size - 1; i++)
269 {
270 final LinkDescriptor link = breadcrumbs.get(i);
271 if (i > 0)
272 {
273 ups.add(UP);
274 }
275 else
276 {
277 link.addRels(HOME);
278 }
279 link.addRels(ups);
280 render(link);
281 }
282 final LinkDescriptor link = breadcrumbs.get(size - 1);
283 if (size == 1)
284 {
285 link.addRels(HOME);
286 }
287 link.addRels(SELF);
288 render(link, true);
289
290 html.end().end();
291 }
292
293 private void render(final LinkDescriptor link)
294 {
295 render(link, false);
296 }
297
298 private void render(final LinkDescriptor link, final boolean last)
299 {
300 final String label = link.getShortLabel();
301 if (StringUtils.isNotBlank(label))
302 {
303 html.li().shortLink(link);
304 if (!last)
305 {
306 html.span().classAttr("divider").text("/").end();
307 }
308
309 html.end();
310 }
311 }
312
313
314
315
316 protected abstract void bodyContents();
317
318 private void footer()
319 {
320 html.div().id("footer");
321 html.div().classAttr("container");
322 html.p().classAttr("muted credit");
323 html.text("powered by ");
324 html.a().href("http://www.smartics.eu/smartics-properties")
325 .text("smartics-properties").end();
326 html.end();
327 html.end();
328 }
329
330 @Override
331 protected final void close()
332 {
333 html.done();
334 try
335 {
336 html.getWriter().flush();
337 }
338 catch (final IOException e)
339 {
340
341 }
342 }
343
344
345
346 }