/* * Copyright (c) 2010 StockPlay development team * All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package com.kapti.cache; import com.kapti.cache.Annotations.Cachable; import com.kapti.cache.Annotations.Invalidates; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import net.sf.cache4j.Cache; import net.sf.cache4j.CacheException; import org.apache.log4j.Logger; /** * \brief InvocationHandler voor objecten beheerd door de caching proxy * * Deze klasse is 1 van de belangrijke pijlers bij het oproepen van een methode * op een object dat geregistreert is bij de proxy cache. Daarbij zal eerst * de cache geraadpleegd worden, waarna eventueel toch een waarde opgevraagd * wordt aan het effectieve object. Die functionaliteit zit vervat in de * invoke() methode van deze klasse, en wordt opgeroepen door het proxyobject, * dat voor de gebruiker als vervanging dient voor het originele object en zo * transparant in gebruik is. */ public class InvocationHandler implements java.lang.reflect.InvocationHandler { private static Logger mLogger = Logger.getLogger(InvocationHandler.class); private Cache cache = null; private Object target = null; public InvocationHandler(Object target, Cache cache) { this.cache = cache; this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Generate a hashcode CallKey callKey = null; callKey = new CallKey(method, args); // Load the annotations Annotation tCachable = method.getAnnotation(Cachable.class); Annotation tInvalidates = method.getAnnotation(Invalidates.class); // Invalidate if (cache != null && tInvalidates != null) { mLogger.debug("invalidating " + cache.getCacheConfig().getCacheId() + ".*"); cache.clear(); } // Look in cache Object result = null; if (cache != null && tCachable != null) { try { result = cache.get(callKey); } catch (CacheException ce) { mLogger.error("could not fetch cache entry", ce); } } // Return if found if (result != null) { Manager.hit(cache, callKey); return result; } // Instantiate result = method.invoke(target, args); // Save if (cache != null && tCachable != null) { Manager.miss(cache, callKey); try { cache.put(callKey, result); } catch (CacheException ce) { mLogger.error("could not save cache entry", ce); } } return result; } }