001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.concurrent.test;
016    
017    import java.lang.reflect.InvocationHandler;
018    import java.lang.reflect.InvocationTargetException;
019    import java.lang.reflect.Method;
020    
021    import java.util.HashMap;
022    import java.util.Map;
023    import java.util.concurrent.Callable;
024    
025    /**
026     * @author Preston Crary
027     */
028    public class MappedMethodCallableInvocationHandler
029            implements InvocationHandler {
030    
031            public MappedMethodCallableInvocationHandler(
032                    Object instance, boolean removeOnCall) {
033    
034                    _instance = instance;
035                    _removeOnCall = removeOnCall;
036            }
037    
038            @Override
039            public Object invoke(Object proxy, Method method, Object[] args)
040                    throws Throwable {
041    
042                    Callable<?> beforeCallable = null;
043    
044                    if (_removeOnCall) {
045                            beforeCallable = _beforeCallables.remove(method);
046                    }
047                    else {
048                            beforeCallable = _beforeCallables.get(method);
049                    }
050    
051                    if (beforeCallable != null) {
052                            beforeCallable.call();
053                    }
054    
055                    try {
056                            return method.invoke(_instance, args);
057                    }
058                    catch (InvocationTargetException ite) {
059                            throw ite.getTargetException();
060                    }
061                    finally {
062                            Callable<?> afterCallable = null;
063    
064                            if (_removeOnCall) {
065                                    afterCallable = _afterCallables.remove(method);
066                            }
067                            else {
068                                    afterCallable = _afterCallables.get(method);
069                            }
070    
071                            if (afterCallable != null) {
072                                    afterCallable.call();
073                            }
074                    }
075            }
076    
077            public void putAfterCallable(Method method, Callable<?> callable) {
078                    _afterCallables.put(method, callable);
079            }
080    
081            public void putBeforeCallable(Method method, Callable<?> callable) {
082                    _beforeCallables.put(method, callable);
083            }
084    
085            private final Map<Method, Callable<?>> _afterCallables = new HashMap<>();
086            private final Map<Method, Callable<?>> _beforeCallables = new HashMap<>();
087            private final Object _instance;
088            private final boolean _removeOnCall;
089    
090    }