001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.monitoring.reporting.web.handler.internal; 018 019 import org.apache.commons.monitoring.MonitoringException; 020 import org.apache.commons.monitoring.reporting.web.handler.api.Template; 021 import org.apache.commons.monitoring.reporting.web.handler.api.TemplateHelper; 022 import org.apache.commons.monitoring.reporting.web.template.MapBuilder; 023 024 import javax.servlet.http.HttpServletRequest; 025 import javax.servlet.http.HttpServletResponse; 026 import java.io.IOException; 027 import java.lang.reflect.InvocationTargetException; 028 import java.lang.reflect.Method; 029 import java.util.List; 030 import java.util.concurrent.CopyOnWriteArrayList; 031 import java.util.regex.Matcher; 032 033 public class Invoker { 034 private final Object instance; 035 private final Method method; 036 private final String name; 037 private final List<ParameterExtractor<?>> parameters = new CopyOnWriteArrayList<ParameterExtractor<?>>(); 038 039 public Invoker(final Object instance, final Method method, final String name) { 040 this.instance = instance; 041 this.method = method; 042 this.name = name; 043 } 044 045 public void invoke(final HttpServletRequest request, final HttpServletResponse response, final Matcher matcher) { 046 final Object[] params = new Object[parameters.size()]; 047 for (int i = 0; i < params.length; i++) { 048 params[i] = parameters.get(i).extract(request, response, matcher); 049 } 050 try { 051 final Object result = method.invoke(instance, params); 052 if (Template.class.isInstance(result)) { 053 final Template template = Template.class.cast(result); 054 final TemplateHelper helper = new TemplateHelperExtractor(name).extract(request, response, matcher); 055 if (template.isHtml()) { 056 helper.renderHtml(template.getTemplate(), template.getUserParams()); 057 } else { 058 helper.renderPlain(template.getTemplate(), template.getUserParams()); 059 } 060 } else if (result != null) { 061 response.getWriter().write(result.toString()); 062 } 063 } catch (final InvocationTargetException e) { 064 throw new MonitoringException(e.getCause()); 065 } catch (final Exception e) { 066 throw new MonitoringException(e); 067 } 068 } 069 070 public void addRequestParameter() { 071 parameters.add(new RequestExtractor()); 072 } 073 074 public void addResponseParameter() { 075 parameters.add(new ResponseExtractor()); 076 } 077 078 public void addTemplateHelper(final String plugin) { 079 parameters.add(new TemplateHelperExtractor(plugin)); 080 } 081 082 public void addSegmentParameter(final Class<?> clazz, final int partIdx) { 083 if (String.class.equals(clazz)) { 084 parameters.add(new StringSegmentExtractor(partIdx)); 085 } else if (Long.TYPE.equals(clazz)) { 086 parameters.add(new LongSegmentExtractor(partIdx)); 087 } else if (Integer.TYPE.equals(clazz)) { 088 parameters.add(new IntSegmentExtractor(partIdx)); 089 } else if (String[].class.equals(clazz)) { 090 parameters.add(new StringArraySegmentExtractor(partIdx)); 091 } else { 092 throw new IllegalArgumentException(clazz.getName() + " not handled"); 093 } 094 } 095 096 protected static interface ParameterExtractor<T> { 097 T extract(HttpServletRequest request, HttpServletResponse response, Matcher matcher); 098 } 099 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 }