/* * Copyright (c) 2012. Piraso Alvin R. de Leon. All Rights Reserved. * * See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The Piraso licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.piraso.proxy; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.lang.Validate; import org.apache.log4j.Logger; import java.lang.reflect.Method; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; /** * Regular expression method interceptor. */ public class RegexMethodInterceptor<T> implements MethodInterceptor { private static final Logger LOG = Logger.getLogger(RegexMethodInterceptor.class); private Map<String, Set<RegexMethodInterceptorListener<T>>> listeners = new LinkedHashMap<String, Set<RegexMethodInterceptorListener<T>>>(); public Object invoke(MethodInvocation invocation) throws Throwable { Set<RegexMethodInterceptorListener<T>> invokeListeners = getListeners(invocation.getMethod()); RegexMethodInterceptorEvent event = fireBeforeCall(invokeListeners, invocation); // skip invocation if(event != null && event.isSkip()) { return null; } Object returnValue; try { // do replacement of arguments if(event != null && event.getReplacedArguments() != null && RegexProxyFactory.MethodInvocationWrapper.class.isInstance(invocation)) { RegexProxyFactory.MethodInvocationWrapper wrapper = (RegexProxyFactory.MethodInvocationWrapper) invocation; wrapper.setReplacedArguments(event.getReplacedArguments()); } returnValue = invocation.proceed(); } catch(Exception e) { fireExceptionCall(invokeListeners, invocation, e); throw e; } return fireAfterCall(invokeListeners, invocation, returnValue); } private RegexMethodInterceptorEvent fireBeforeCall(Set<RegexMethodInterceptorListener<T>> listeners, MethodInvocation invocation) { try { RegexMethodInterceptorEvent<T> event = new RegexMethodInterceptorEvent<T>(this, invocation); for(RegexMethodInterceptorListener<T> listener : listeners) { listener.beforeCall(event); } return event; } catch(Exception e) { LOG.warn(e.getMessage(), e); } return null; } private void fireExceptionCall(Set<RegexMethodInterceptorListener<T>> listeners, MethodInvocation invocation, Exception ex) { try { RegexMethodInterceptorEvent<T> event = new RegexMethodInterceptorEvent<T>(this, invocation); event.setException(ex); for(RegexMethodInterceptorListener<T> listener : listeners) { listener.exceptionCall(event); } } catch(Exception e) { LOG.warn(e.getMessage(), e); } } private Object fireAfterCall(Set<RegexMethodInterceptorListener<T>> listeners, MethodInvocation invocation, Object returnedValue) { try { RegexMethodInterceptorEvent<T> event = new RegexMethodInterceptorEvent<T>(this, invocation, returnedValue); for(RegexMethodInterceptorListener<T> listener : listeners) { listener.afterCall(event); } return event.getReturnedValue(); } catch(Exception e) { LOG.warn(e.getMessage(), e); } return returnedValue; } private Set<RegexMethodInterceptorListener<T>> getListeners(Method method) { Set<RegexMethodInterceptorListener<T>> matchListeners = new HashSet<RegexMethodInterceptorListener<T>>(); String methodName = method.getName(); for(Map.Entry<String, Set<RegexMethodInterceptorListener<T>>> entry : listeners.entrySet()) { if(methodName.matches(entry.getKey())) { matchListeners.addAll(entry.getValue()); } } return matchListeners; } public void addAllMethodListener(Map<String, Set<RegexMethodInterceptorListener<T>>> newListeners) { for(Map.Entry<String, Set<RegexMethodInterceptorListener<T>>> entry : newListeners.entrySet()) { for(RegexMethodInterceptorListener<T> newListener : entry.getValue()) { addMethodListener(entry.getKey(), newListener); } } } public void addMethodListener(String regex, RegexMethodInterceptorListener<T> listener) { Validate.notNull("listener cannot be null."); Set<RegexMethodInterceptorListener<T>> set = listeners.get(regex); if(set == null) { set = new HashSet<RegexMethodInterceptorListener<T>>(); listeners.put(regex, set); } set.add(listener); } }