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 java.io.OutputStream;
19 import java.io.PrintWriter;
20 import java.io.StringWriter;
21 import java.util.List;
22
23 import javax.ws.rs.core.MultivaluedMap;
24 import javax.ws.rs.core.UriInfo;
25
26 import org.apache.commons.lang3.StringUtils;
27
28 import de.smartics.exceptions.i18n.CauseTrailMessages;
29 import de.smartics.exceptions.i18n.LocalizedException;
30 import de.smartics.exceptions.i18n.message.MessageType;
31 import de.smartics.exceptions.i18n.message.Messages;
32 import de.smartics.html5.jatl.HtmlResourceContext;
33 import de.smartics.properties.admin.domain.model.CannotInitializeManagedApplicationException;
34 import de.smartics.properties.admin.domain.model.Paths;
35 import de.smartics.properties.admin.resources.controller.ApiResource;
36 import de.smartics.properties.admin.resources.representation.share.BreadcrumbHelper;
37 import de.smartics.properties.admin.resources.representation.share.LinkDescriptorFactory;
38 import de.smartics.resteasy.hypermedia.renderer.LinkDescriptor;
39 import de.smartics.resteasy.hypermedia.renderer.LocalizationProvider;
40 import de.smartics.resteasy.hypermedia.renderer.ResourceContext;
41
42
43
44
45 public class ExceptionHtmlRepresentationRenderer extends
46 AbstractHtmlRepresentationRenderer<Throwable>
47 {
48
49
50
51
52
53
54
55
56
57 private final Throwable domainObject;
58
59
60
61
62
63
64
65
66
67
68
69
70 public ExceptionHtmlRepresentationRenderer(
71 final HtmlResourceContext htmlContext, final Throwable domainObject,
72 final OutputStream entityStream)
73 {
74 super(htmlContext, entityStream);
75 this.domainObject = domainObject;
76 }
77
78
79
80
81
82
83
84
85
86 @Override
87 protected String getTitle()
88 {
89 return "Exception raised";
90 }
91
92
93
94 @Override
95 protected void bodyContents()
96 {
97 if (domainObject instanceof LocalizedException)
98 {
99 renderSmartException();
100 }
101 else if (domainObject instanceof CannotInitializeManagedApplicationException)
102 {
103 renderCannotInitializeManagedApplicationException();
104 }
105 else
106 {
107 renderThrowable();
108 }
109 }
110
111 private void renderSmartException()
112 {
113 final LocalizedException localizedException =
114 (LocalizedException) domainObject;
115
116 final Messages messages = localizedException.createMessages();
117 renderPageTitle(messages.getMessage(MessageType.TITLE));
118 html.p().text("An exception has been raised!").end();
119
120 html.h2().text("Raised Exception").end();
121 renderException(localizedException, messages);
122
123 final CauseTrailMessages causeTrail = localizedException.getCauseTrail();
124 for (final Messages causeMessages : causeTrail.getTrail())
125 {
126 html.h2().text(messages.getMessage(MessageType.SUMMARY)).end();
127 renderException(null, causeMessages);
128 }
129 html.h2().text("Stack Trace").end();
130 html.p().text("This is the stack trace to the exception:").end();
131 final StringBuilder buffer = new StringBuilder();
132 for (final StackTraceElement element : localizedException.getStackTrace())
133 {
134 buffer.append(" at ").append(element.getClassName()).append(".")
135 .append(element.getMethodName()).append(":")
136 .append(element.getLineNumber()).append('\n');
137 }
138 final String text = buffer.toString();
139 html.pre().text(text).end();
140 }
141
142 private void renderCannotInitializeManagedApplicationException()
143 {
144 renderPageTitle("!?!");
145 html.p().text("An exception has been raised!").end();
146
147 html.div().classAttr("alert alert-info");
148 html.button().type("button").classAttr("close")
149 .attr("data-dismiss", "alert").raw("×").end();
150 html.h4().text("Managed Application Problem").end();
151 html.text("The application to be managed cannot be initialized."
152 + " Maybe you want to provide the required boot properties via JNDI?");
153 html.p();
154 final LinkDescriptor link =
155 linkDescriptorFactory.createDescriptor(ApiResource.JNDI, "getAsHtml");
156 html.link(link);
157 html.end();
158
159 html.end();
160
161 renderMessageAndStackTrace();
162 }
163
164 private void renderThrowable()
165 {
166 renderPageTitle("!?!");
167 html.p().text("An exception has been raised!").end();
168
169 renderMessageAndStackTrace();
170 }
171
172 private void renderMessageAndStackTrace()
173 {
174 final String message = domainObject.getLocalizedMessage();
175 html.pre().text(message).end();
176
177 html.h2().text("Stack Trace").end();
178 html.p().text("This is the stack trace to the exception:").end();
179 final StringWriter writer = new StringWriter();
180 final PrintWriter print = new PrintWriter(writer);
181 domainObject.printStackTrace(print);
182 final String stacktrace = writer.toString();
183 html.pre().text(stacktrace).end();
184 }
185
186 private void renderException(final LocalizedException e,
187 final Messages messages)
188 {
189 if (e != null)
190 {
191 html.h3().text("Metadata").end();
192 html.table().classAttr("table table-striped");
193 renderMetadataRow("Code", e.getCode());
194 renderMetadataRow("ID", e.getId());
195 renderMetadataRow("Timestamp", e.getTime());
196 html.end();
197 }
198
199 renderSection(messages, "Summary", MessageType.SUMMARY);
200 renderSection(messages, "Details", MessageType.DETAILS);
201 renderSection(messages, "Implications",
202 MessageType.IMPLICATIONS_ON_CURRENT_TASK);
203 renderSection(messages, "Todo", MessageType.WHAT_TO_DO_NOW);
204 renderSection(messages, "URL", MessageType.URL);
205 }
206
207 private void renderMetadataRow(final String label, final Object value)
208 {
209 html.tr().th().text(label).end().td().text(String.valueOf(value)).end()
210 .end();
211 }
212
213 private void renderSection(final Messages messages, final String label,
214 final MessageType type)
215 {
216 final String message = messages.getMessage(type);
217 if (StringUtils.isNotBlank(message))
218 {
219 html.h3().text(label).end();
220 html.p().text(message).end();
221 }
222 }
223
224 @Override
225 protected List<LinkDescriptor> breadcrumbLinks()
226 {
227 final ResourceContext context = this.htmlContext.getContext();
228 final LocalizationProvider provider = context.getL7nProvider();
229 final UriInfo uriInfo = context.getUriInfo();
230 final LinkDescriptorFactory factory =
231 new LinkDescriptorFactory(uriInfo, provider);
232 final BreadcrumbHelper breadcrumb =
233 new BreadcrumbHelper(factory, "getAsHtml");
234
235 final String path = uriInfo.getPath();
236 if (path.startsWith(Paths.PATH_SECURITY))
237 {
238 return breadcrumb.security();
239 }
240 if (path.startsWith(Paths.PATH_JNDI))
241 {
242 return breadcrumb.jndi();
243 }
244 else if (path.startsWith(Paths.PATH_PROPERTY_DESCRIPTORS))
245 {
246 return breadcrumbDescriptors(uriInfo, breadcrumb);
247 }
248 else if (path.startsWith(Paths.PATH_CONFIGURATIONS))
249 {
250 return breadcrumbConfigurations(uriInfo, breadcrumb);
251 }
252 else
253 {
254 return breadcrumb.home();
255 }
256 }
257
258 private List<LinkDescriptor> breadcrumbDescriptors(final UriInfo uriInfo,
259 final BreadcrumbHelper breadcrumb)
260 {
261 final MultivaluedMap<String, String> params = uriInfo.getPathParameters();
262 final String propertyKey = params.getFirst(Paths.PARAM_PROPERTY_KEY);
263
264 final List<LinkDescriptor> descriptors;
265 if (StringUtils.isBlank(propertyKey))
266 {
267 descriptors = breadcrumb.descriptors();
268 }
269 else
270 {
271 descriptors = breadcrumb.descriptor(propertyKey);
272 }
273 return descriptors;
274 }
275
276 private List<LinkDescriptor> breadcrumbConfigurations(final UriInfo uriInfo,
277 final BreadcrumbHelper breadcrumb)
278 {
279 final MultivaluedMap<String, String> params = uriInfo.getPathParameters();
280 final String configurationKey =
281 params.getFirst(Paths.PARAM_CONFIGURATION_KEY);
282 final String propertyKey = params.getFirst(Paths.PARAM_PROPERTY_KEY);
283
284 final List<LinkDescriptor> descriptors;
285 if (StringUtils.isBlank(configurationKey))
286 {
287 descriptors = breadcrumb.configurations();
288 }
289 else if (StringUtils.isBlank(propertyKey))
290 {
291 descriptors = breadcrumb.configuration(configurationKey);
292 }
293 else
294 {
295 descriptors = breadcrumb.property(configurationKey, propertyKey);
296 }
297 return descriptors;
298 }
299
300
301
302 }