1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.monitoring.reporting.web.handler.internal;
18
19 import org.apache.commons.monitoring.MonitoringException;
20 import org.apache.commons.monitoring.reporting.web.handler.api.Template;
21 import org.apache.commons.monitoring.reporting.web.handler.api.TemplateHelper;
22 import org.apache.commons.monitoring.reporting.web.template.MapBuilder;
23
24 import javax.servlet.http.HttpServletRequest;
25 import javax.servlet.http.HttpServletResponse;
26 import java.io.IOException;
27 import java.lang.reflect.InvocationTargetException;
28 import java.lang.reflect.Method;
29 import java.util.List;
30 import java.util.concurrent.CopyOnWriteArrayList;
31 import java.util.regex.Matcher;
32
33 public class Invoker {
34 private final Object instance;
35 private final Method method;
36 private final String name;
37 private final List<ParameterExtractor<?>> parameters = new CopyOnWriteArrayList<ParameterExtractor<?>>();
38
39 public Invoker(final Object instance, final Method method, final String name) {
40 this.instance = instance;
41 this.method = method;
42 this.name = name;
43 }
44
45 public void invoke(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
46 final Object[] params = new Object[parameters.size()];
47 for (int i = 0; i < params.length; i++) {
48 params[i] = parameters.get(i).extract(request, response, matcher);
49 }
50 try {
51 final Object result = method.invoke(instance, params);
52 if (Template.class.isInstance(result)) {
53 final Template template = Template.class.cast(result);
54 final TemplateHelper helper = new TemplateHelperExtractor(name).extract(request, response, matcher);
55 if (template.isHtml()) {
56 helper.renderHtml(template.getTemplate(), template.getUserParams());
57 } else {
58 helper.renderPlain(template.getTemplate(), template.getUserParams());
59 }
60 } else if (result != null) {
61 response.getWriter().write(result.toString());
62 }
63 } catch (final InvocationTargetException e) {
64 throw new MonitoringException(e.getCause());
65 } catch (final Exception e) {
66 throw new MonitoringException(e);
67 }
68 }
69
70 public void addRequestParameter() {
71 parameters.add(new RequestExtractor());
72 }
73
74 public void addResponseParameter() {
75 parameters.add(new ResponseExtractor());
76 }
77
78 public void addTemplateHelper(final String plugin) {
79 parameters.add(new TemplateHelperExtractor(plugin));
80 }
81
82 public void addSegmentParameter(final Class<?> clazz, final int partIdx) {
83 if (String.class.equals(clazz)) {
84 parameters.add(new StringSegmentExtractor(partIdx));
85 } else if (Long.TYPE.equals(clazz)) {
86 parameters.add(new LongSegmentExtractor(partIdx));
87 } else if (Integer.TYPE.equals(clazz)) {
88 parameters.add(new IntSegmentExtractor(partIdx));
89 } else if (String[].class.equals(clazz)) {
90 parameters.add(new StringArraySegmentExtractor(partIdx));
91 } else {
92 throw new IllegalArgumentException(clazz.getName() + " not handled");
93 }
94 }
95
96 protected static interface ParameterExtractor<T> {
97 T extract(HttpServletRequest request, HttpServletResponse response, Matcher matcher);
98 }
99
100 protected static class TemplateHelperExtractor implements ParameterExtractor<TemplateHelper> {
101 private final String plugin;
102
103 public TemplateHelperExtractor(final String plugin) {
104 this.plugin = plugin;
105 }
106
107 @Override
108 public TemplateHelper extract(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
109 try {
110 return new TemplateHelper(response.getWriter(), new MapBuilder<String, Object>().set("templateId", plugin).build());
111 } catch (final IOException e) {
112 throw new MonitoringException(e);
113 }
114 }
115 }
116
117 protected static class RequestExtractor implements ParameterExtractor<HttpServletRequest> {
118 @Override
119 public HttpServletRequest extract(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
120 return request;
121 }
122 }
123
124 protected static class ResponseExtractor implements ParameterExtractor<HttpServletResponse> {
125 @Override
126 public HttpServletResponse extract(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
127 return response;
128 }
129 }
130
131 protected static class StringSegmentExtractor implements ParameterExtractor<String> {
132 private final int index;
133
134 public StringSegmentExtractor(final int index) {
135 this.index = index;
136 }
137
138 @Override
139 public String extract(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
140 return matcher.group(index);
141 }
142 }
143
144 protected static class StringArraySegmentExtractor implements ParameterExtractor<String[]> {
145 private final int index;
146
147 public StringArraySegmentExtractor(final int index) {
148 this.index = index;
149 }
150
151 @Override
152 public String[] extract(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
153 return matcher.group(index).split("/");
154 }
155 }
156
157 protected static class LongSegmentExtractor implements ParameterExtractor<Long> {
158 private final int index;
159
160 public LongSegmentExtractor(final int index) {
161 this.index = index;
162 }
163
164 @Override
165 public Long extract(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
166 return Long.parseLong(matcher.group(index));
167 }
168 }
169
170 protected static class IntSegmentExtractor implements ParameterExtractor<Integer> {
171 private final int index;
172
173 public IntSegmentExtractor(final int index) {
174 this.index = index;
175 }
176
177 @Override
178 public Integer extract(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) {
179 return Integer.parseInt(matcher.group(index));
180 }
181 }
182 }