/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos 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 2 of the License, or (at your option) any later version. Cyclos 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 Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.utils; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import nl.strohalm.cyclos.entities.accounts.transactions.TransferListener; import nl.strohalm.cyclos.services.sms.ISmsContext; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; /** * Handler for custom objects creation, such as {@link TransferListener}, {@link ISmsContext} and so on Regular Cache is not used, as here we have * live instances, maybe they are not serializable, for example, to be on cache * @author luis */ public class CustomObjectHandlerImpl implements CustomObjectHandler, ApplicationContextAware, DisposableBean { private ApplicationContext applicationContext; private final Map<String, Object> beans = new ConcurrentHashMap<String, Object>(); @Override public boolean contains(final String className) { return beans.containsKey(className); } @Override public void destroy() throws Exception { // Attempt to clean up all cached instances for (Object object : beans.values()) { if (object instanceof DisposableBean) { ((DisposableBean) object).destroy(); } } beans.clear(); } /** * Returns the object with the given class */ @Override @SuppressWarnings("unchecked") public <T> T get(final String className) { Object bean = beans.get(className); if (bean == null) { bean = doGet(className); } return (T) bean; } @Override public <T> T getBean(final Class<T> beanType) { return applicationContext.getBean(beanType); } @Override public void setApplicationContext(final ApplicationContext applicationContext) { this.applicationContext = applicationContext; } private synchronized Object doGet(final String className) { // Check again for the cache here, inside the sync method Object bean = beans.get(className); if (bean != null) { return bean; } try { AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory(); Class<?> beanClass = Class.forName(className); bean = factory.createBean(beanClass, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false); factory.initializeBean(bean, beanClass.getSimpleName() + "#" + System.identityHashCode(bean)); beans.put(className, bean); return bean; } catch (Exception e) { throw new IllegalArgumentException("Couldn't instantiate class " + className, e); } } }