/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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 Lesser General Public License for more * details. */ package com.liferay.portal.spring.context; import com.liferay.portal.kernel.configuration.Configuration; import com.liferay.portal.kernel.configuration.ConfigurationFactoryUtil; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.portlet.PortletClassLoaderUtil; import com.liferay.portal.kernel.util.AggregateClassLoader; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.ClassLoaderUtil; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.kernel.util.PropsKeys; import com.liferay.portal.security.lang.DoPrivilegedFactory; import com.liferay.portal.spring.util.FilterClassLoader; import com.liferay.portal.util.PropsValues; import java.io.FileNotFoundException; import java.util.List; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.web.context.support.XmlWebApplicationContext; /** * <p> * This web application context will first load bean definitions in the * portalContextConfigLocation parameter in web.xml. Then, the context will load * bean definitions specified by the property "spring.configs" in * service.properties. * </p> * * @author Brian Wing Shun Chan * @see PortletContextLoaderListener */ public class PortletApplicationContext extends XmlWebApplicationContext { public static ClassLoader getBeanClassLoader() { return _pacl.getBeanClassLoader(); } public PortletApplicationContext() { setClassLoader(getBeanClassLoader()); } public interface PACL { public ClassLoader getBeanClassLoader(); } @Override protected String[] getDefaultConfigLocations() { return new String[0]; } protected String[] getPortletConfigLocations() { String[] configLocations = getConfigLocations(); ClassLoader classLoader = PortletClassLoaderUtil.getClassLoader(); Configuration serviceBuilderPropertiesConfiguration = null; try { serviceBuilderPropertiesConfiguration = ConfigurationFactoryUtil.getConfiguration( classLoader, "service"); } catch (Exception e) { if (_log.isDebugEnabled()) { _log.debug("Unable to read service.properties"); } return configLocations; } // Remove old spring XMLs to ensure they are not read List<String> serviceBuilderPropertiesConfigLocations = ListUtil.fromArray( serviceBuilderPropertiesConfiguration.getArray( PropsKeys.SPRING_CONFIGS)); serviceBuilderPropertiesConfigLocations.remove( "WEB-INF/classes/META-INF/base-spring.xml"); serviceBuilderPropertiesConfigLocations.remove( "WEB-INF/classes/META-INF/cluster-spring.xml"); serviceBuilderPropertiesConfigLocations.remove( "WEB-INF/classes/META-INF/hibernate-spring.xml"); serviceBuilderPropertiesConfigLocations.remove( "WEB-INF/classes/META-INF/infrastructure-spring.xml"); return ArrayUtil.append( PropsValues.SPRING_PORTLET_CONFIGS, configLocations, serviceBuilderPropertiesConfigLocations.toArray( new String[serviceBuilderPropertiesConfigLocations.size()])); } @Override protected void initBeanDefinitionReader( XmlBeanDefinitionReader xmlBeanDefinitionReader) { xmlBeanDefinitionReader.setBeanClassLoader(getBeanClassLoader()); } protected void injectExplicitBean( Class<?> clazz, BeanDefinitionRegistry beanDefinitionRegistry) { beanDefinitionRegistry.registerBeanDefinition( clazz.getName(), new RootBeanDefinition(clazz)); } protected void injectExplicitBeans( BeanDefinitionRegistry beanDefinitionRegistry) { injectExplicitBean(DoPrivilegedFactory.class, beanDefinitionRegistry); } @Override protected void loadBeanDefinitions( XmlBeanDefinitionReader xmlBeanDefinitionReader) { String[] configLocations = getPortletConfigLocations(); if (configLocations == null) { return; } BeanDefinitionRegistry beanDefinitionRegistry = xmlBeanDefinitionReader.getBeanFactory(); injectExplicitBeans(beanDefinitionRegistry); for (String configLocation : configLocations) { try { xmlBeanDefinitionReader.loadBeanDefinitions(configLocation); } catch (Exception e) { Throwable cause = e.getCause(); if (cause instanceof FileNotFoundException) { if (_log.isWarnEnabled()) { _log.warn(cause.getMessage()); } } else { _log.error(e, e); } } } } private static final Log _log = LogFactoryUtil.getLog( PortletApplicationContext.class); private static final PACL _pacl = new NoPACL(); private static class NoPACL implements PACL { @Override public ClassLoader getBeanClassLoader() { ClassLoader beanClassLoader = AggregateClassLoader.getAggregateClassLoader( new ClassLoader[] { PortletClassLoaderUtil.getClassLoader(), ClassLoaderUtil.getPortalClassLoader() }); return new FilterClassLoader(beanClassLoader); } } }