/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.server.security.extender; import java.io.IOException; import org.eclipse.gemini.blueprint.io.OsgiBundleResourcePatternResolver; import org.eclipse.gemini.blueprint.util.BundleDelegatingClassLoader; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.springframework.beans.BeansException; import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.core.io.Resource; import org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext; import de.fhg.igd.osgi.util.ChainedClassLoader; import eu.esdihumboldt.hale.server.security.extender.internal.Activator; /** * A web application context which can load context configuration resources from * security bundles. These security bundles are found through an extender * pattern. They are registered by this bundle's activator. * * @author Michel Kraemer */ public class SecuredBundleXmlWebApplicationContext extends OsgiBundleXmlWebApplicationContext implements SecuredApplicationContext { /** * The META-INF directory */ private static final String META_INF = "/META-INF/"; /** * The cached class loader returned by {@link #getClassLoader()} */ private transient ClassLoader _classLoader; /** * True if security management is enabled, false if everyone is allowed to * do everything. Will be set to false when the default configuration file * is used (because this file allows everything), will be set to true when * any other file is used. The default value is true, because we want to be * restrictive in the beginning. */ private boolean _securityEnabled = true; /** * @see OsgiBundleXmlWebApplicationContext#loadBeanDefinitions(XmlBeanDefinitionReader) */ @Override protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { // load bean definitions of the war bundle super.loadBeanDefinitions(reader); // load security bean definitions... BundleContext ctx = Activator.getContext(); Bundle securitybnd = ctx.getBundle(); OsgiBundleResourcePatternResolver resolver = new OsgiBundleResourcePatternResolver( securitybnd); // try to load security bean definitions from a fragment String loc = META_INF + "applicationContext-security.xml"; Resource[] resources = resolver.getResources(loc); int n = 0; if (resources != null) { // check if the resources exist for (Resource r : resources) { if (r.exists()) { ++n; } } if (n > 0) { n = reader.loadBeanDefinitions(resources); } } if (n == 0) { // load default security bean definitions from this bundle loc = META_INF + "applicationContext-security-default.xml"; resources = resolver.getResources(loc); if (resources != null) { n = reader.loadBeanDefinitions(resources); } if (n == 0) { throw new RuntimeException("Could not load default security " + "bean definitions"); } // the default definition file allows everything, so set // security management to disabled _securityEnabled = false; } } /** * @see OsgiBundleXmlWebApplicationContext#getClassLoader() */ @Override public ClassLoader getClassLoader() { ClassLoader cl = super.getClassLoader(); if (cl == null) { // the class loader has not been set yet return null; } if (_classLoader == null) { BundleContext ctx = Activator.getContext(); Bundle securitybnd = ctx.getBundle(); ClassLoader bndcl = BundleDelegatingClassLoader.createBundleClassLoaderFor(securitybnd); _classLoader = new ChainedClassLoader(cl, bndcl); } return _classLoader; } /** * @see OsgiBundleXmlWebApplicationContext#setClassLoader(ClassLoader) */ @Override public void setClassLoader(ClassLoader classLoader) { _classLoader = null; super.setClassLoader(classLoader); } @Override public boolean isSecurityEnabled() { return _securityEnabled; } }