View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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 }