/** * OLAT - Online Learning and Training<br> * http://www.olat.org * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> * University of Zurich, Switzerland. * <hr> * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * This file has been modified by the OpenOLAT community. Changes are licensed * under the Apache 2.0 license as the original file. * <p> */ package org.olat.core; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import javax.servlet.ServletContext; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.core.io.Resource; import org.springframework.web.context.ServletContextAware; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; /** * Description:<br> * The core spring factory is used to load resources and spring beans. The * application context is generated from XML files. Normally you should not use this class and instead * inject dependencies at xml level or with autowire! * * <P> * Initial Date: 12.06.2006 <br> * * @author patrickb */ public class CoreSpringFactory implements ServletContextAware, BeanFactoryAware { private static final OLog log = Tracing.createLoggerFor(CoreSpringFactory.class); // Access servletContext only for spring beans admin-functions public static ServletContext servletContext; private static DefaultListableBeanFactory beanFactory; private static Map<Class<?>, String> idToBeans = new ConcurrentHashMap<Class<?>, String>(); /** * [used by spring only] */ private CoreSpringFactory() { // } /** * wrapper to the applicationContext (we are facading spring's * applicationContext) * * @param path * a path in spring notation (e.g. "classpath*:/*.hbm.xml", see * springframework.org) * @return the resources found */ public static Resource[] getResources(String path) { Resource[] res; try { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); res = context.getResources(path); } catch (IOException e) { throw new AssertException( "i/o error while asking for resources, path:" + path); } return res; } public static String resolveProperty(String name) { String rv = beanFactory.resolveEmbeddedValue("${" + name + "}"); return rv; } public static void autowireObject(Object bean) { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); context.getAutowireCapableBeanFactory().autowireBean(bean); } /** * @param beanName * The bean name to check for. Be sure the bean does exist, * otherwise an NoSuchBeanDefinitionException will be thrown * @return The bean * */ public static Object getBean(String beanName) { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); return context.getBean(beanName); } /** * @param interfaceImpl * The bean name to check for. Be sure the bean does exist, * otherwise an NoSuchBeanDefinitionException will be thrown * @return The bean */ public static <T> T getImpl(Class<T> interfaceClass) { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); if(context == null) { log.warn("Calling this bean before the Spring web application is started: " + interfaceClass.getName()); return null; } if(idToBeans.containsKey(interfaceClass)) { String id = idToBeans.get(interfaceClass); @SuppressWarnings("unchecked") T bean = (T)context.getBean(id); if(bean != null) { return bean; } } Map<String, T> m = context.getBeansOfType(interfaceClass); if (m.size() == 1) { Entry<String,T> e =m.entrySet().iterator().next(); idToBeans.put(interfaceClass, e.getKey()); return e.getValue(); } throw new OLATRuntimeException("found " + m.size() + " bean for: "+ interfaceClass +". Calling this method should only find one bean!", null); } /** * @param beanName * The bean name to check for. Be sure the bean does exist, * otherwise an NoSuchBeanDefinitionException will be thrown * @return The bean */ public static Object getBean(Class<?> interfaceName) { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); Map<String, ?> m = context.getBeansOfType(interfaceName); if (m.size() > 1) { //more than one bean found -> excecption throw new OLATRuntimeException("found more than one bean for: "+interfaceName +". Calling this method should only find one bean!", null); } else if (m.size() == 1 ) { return new ArrayList<Object>(m.values()).get(0); } //fallback for beans named like the fully qualified path (legacy) Object o = context.getBean(interfaceName.getName()); return o; } /** * * @param beanName * @return */ public static boolean containsSingleton(String beanName) { return beanFactory.containsSingleton(beanName); } /** * @param beanName * The bean name to check for * @return true if such a bean does exist, false * otherwhise. But if such a bean definition exists it will get created! * Use the containsSingleton to check for lazy init beans whether they * are instantiated or not. */ public static boolean containsBean(String beanName) { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); return context.containsBean(beanName); } /** * * @param classz * @return */ public static boolean containsBean(Class<?> classz) { ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); return context.getBeansOfType(classz).size() > 0; } /** * normally you should not use this! * At the moment it is used for calling the shutdown hook in Spring * @return the OLAT Spring application Context */ public static WebApplicationContext getContext() { return WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); } /** * [used by spring] * @see org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet.ServletContext) */ @Override public void setServletContext(ServletContext servletContext) { CoreSpringFactory.servletContext = servletContext; } public static <T> Map<String, T> getBeansOfType(Class<T> extensionType) { WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(CoreSpringFactory.servletContext); Map<String, T> beans = context.getBeansOfType(extensionType); Map<String, T> clone = new HashMap<String, T>(beans); return clone; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { CoreSpringFactory.beanFactory = (DefaultListableBeanFactory) beanFactory; } }