001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.event.support; 020 021import java.lang.reflect.Method; 022import java.lang.reflect.Modifier; 023 024/** 025 * A event listener that invokes a target object's method that accepts a single event argument. 026 * 027 * @since 1.3 028 */ 029public class SingleArgumentMethodEventListener implements TypedEventListener { 030 031 private final Object target; 032 private final Method method; 033 034 public SingleArgumentMethodEventListener(Object target, Method method) { 035 this.target = target; 036 this.method = method; 037 //assert that the method is defined as expected: 038 getMethodArgumentType(method); 039 040 assertPublicMethod(method); 041 } 042 043 public Object getTarget() { 044 return this.target; 045 } 046 047 public Method getMethod() { 048 return this.method; 049 } 050 051 private void assertPublicMethod(Method method) { 052 int modifiers = method.getModifiers(); 053 if (!Modifier.isPublic(modifiers)) { 054 throw new IllegalArgumentException("Event handler method [" + method + "] must be public."); 055 } 056 } 057 058 public boolean accepts(Object event) { 059 return event != null && getEventType().isInstance(event); 060 } 061 062 public Class getEventType() { 063 return getMethodArgumentType(getMethod()); 064 } 065 066 public void onEvent(Object event) { 067 Method method = getMethod(); 068 try { 069 method.invoke(getTarget(), event); 070 } catch (Exception e) { 071 throw new IllegalStateException("Unable to invoke event handler method [" + method + "].", e); 072 } 073 } 074 075 protected Class getMethodArgumentType(Method method) { 076 Class[] paramTypes = method.getParameterTypes(); 077 if (paramTypes.length != 1) { 078 //the default implementation expects a single typed argument and nothing more: 079 String msg = "Event handler methods must accept a single argument."; 080 throw new IllegalArgumentException(msg); 081 } 082 return paramTypes[0]; 083 } 084}