org.apache.felix.cm.impl.ConfigurationAdminImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.felix.configadmin Show documentation
Show all versions of org.apache.felix.configadmin Show documentation
Implementation of the OSGi Configuration Admin Service Specification 1.6
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.cm.impl;
import java.io.IOException;
import org.osgi.framework.Bundle;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationPermission;
import org.osgi.service.log.LogService;
/**
* The ConfigurationAdminImpl
is the per-bundle frontend to the
* configuration manager. Instances of this class are created on-demand for
* each bundle trying to get hold of the ConfigurationAdmin
* service.
*/
public class ConfigurationAdminImpl implements ConfigurationAdmin
{
// The configuration manager to which most of the tasks are delegated
private volatile ConfigurationManager configurationManager;
// The bundle for which this instance has been created
private volatile Bundle bundle;
ConfigurationAdminImpl( ConfigurationManager configurationManager, Bundle bundle )
{
this.configurationManager = configurationManager;
this.bundle = bundle;
}
void dispose()
{
bundle = null;
configurationManager = null;
}
Bundle getBundle()
{
return bundle;
}
//---------- ConfigurationAdmin interface ---------------------------------
/* (non-Javadoc)
* @see org.osgi.service.cm.ConfigurationAdmin#createFactoryConfiguration(java.lang.String)
*/
@Override
public Configuration createFactoryConfiguration( String factoryPid ) throws IOException
{
final ConfigurationManager configurationManager = getConfigurationManager();
Log.logger.log( LogService.LOG_DEBUG, "createFactoryConfiguration(factoryPid={0})", new Object[]
{ factoryPid } );
// FELIX-3360: new factory configuration with implicit binding is dynamic
ConfigurationImpl config = configurationManager.createFactoryConfiguration( factoryPid, null );
config.setDynamicBundleLocation( Activator.getLocation(this.getBundle()), false );
return this.wrap( config );
}
/* (non-Javadoc)
* @see org.osgi.service.cm.ConfigurationAdmin#createFactoryConfiguration(java.lang.String, java.lang.String)
*/
@Override
public Configuration createFactoryConfiguration( String factoryPid, String location ) throws IOException
{
final ConfigurationManager configurationManager = getConfigurationManager();
Log.logger.log( LogService.LOG_DEBUG, "createFactoryConfiguration(factoryPid={0}, location={1})",
new Object[]
{ factoryPid, location } );
// CM 1.4 / 104.13.2.3
this.checkPermission( configurationManager, ( location == null ) ? "*" : location, false );
ConfigurationImpl config = configurationManager.createFactoryConfiguration( factoryPid, location );
return this.wrap( config );
}
/* (non-Javadoc)
* @see org.osgi.service.cm.ConfigurationAdmin#getConfiguration(java.lang.String)
*/
@Override
public Configuration getConfiguration( String pid ) throws IOException
{
final ConfigurationManager configurationManager = getConfigurationManager();
Log.logger.log( LogService.LOG_DEBUG, "getConfiguration(pid={0})", new Object[]
{ pid } );
ConfigurationImpl config = configurationManager.getConfiguration( pid );
if ( config == null )
{
config = configurationManager.createConfiguration( pid, null );
// FELIX-3360: configuration creation with implicit binding is dynamic
config.setDynamicBundleLocation( Activator.getLocation(getBundle()), false );
}
else
{
if ( config.getBundleLocation() == null )
{
Log.logger.log( LogService.LOG_DEBUG, "Binding configuration {0} (isNew: {1}) to bundle {2}",
new Object[]
{ config.getPid(), config.isNew() ? Boolean.TRUE : Boolean.FALSE,
Activator.getLocation(this.getBundle()) } );
// FELIX-3360: first implicit binding is dynamic
config.setDynamicBundleLocation( Activator.getLocation(getBundle()), true );
}
else
{
// CM 1.4 / 104.13.2.3
this.checkPermission( configurationManager, config.getBundleLocation(), false );
}
}
return this.wrap( config );
}
/* (non-Javadoc)
* @see org.osgi.service.cm.ConfigurationAdmin#getConfiguration(java.lang.String, java.lang.String)
*/
@Override
public Configuration getConfiguration( String pid, String location ) throws IOException
{
final ConfigurationManager configurationManager = getConfigurationManager();
Log.logger.log( LogService.LOG_DEBUG, "getConfiguration(pid={0}, location={1})", new Object[]
{ pid, location } );
// CM 1.4 / 104.13.2.3
this.checkPermission( configurationManager, ( location == null ) ? "*" : location, false );
ConfigurationImpl config = configurationManager.getConfiguration( pid );
if ( config == null )
{
config = configurationManager.createConfiguration( pid, location );
}
else
{
final String configLocation = config.getBundleLocation();
this.checkPermission( configurationManager, ( configLocation == null ) ? "*" : configLocation, false );
}
return this.wrap( config );
}
/* (non-Javadoc)
* @see org.osgi.service.cm.ConfigurationAdmin#listConfigurations(java.lang.String)
*/
@Override
public Configuration[] listConfigurations( String filter ) throws IOException, InvalidSyntaxException
{
final ConfigurationManager configurationManager = getConfigurationManager();
Log.logger.log( LogService.LOG_DEBUG, "listConfigurations(filter={0})", new Object[]
{ filter } );
ConfigurationImpl ci[] = configurationManager.listConfigurations( this, filter );
if ( ci == null || ci.length == 0 )
{
return null;
}
Configuration[] cfgs = new Configuration[ci.length];
for ( int i = 0; i < cfgs.length; i++ )
{
cfgs[i] = this.wrap( ci[i] );
}
return cfgs;
}
//---------- Security checks ----------------------------------------------
private Configuration wrap( ConfigurationImpl configuration )
{
return new ConfigurationAdapter( this, configuration );
}
/**
* Returns true
if the current access control context (call
* stack) has the CONFIGURE permission.
*/
boolean hasPermission( final ConfigurationManager configurationManager, String name )
{
try
{
checkPermission(configurationManager, name, false);
return true;
}
catch ( SecurityException se )
{
return false;
}
}
/**
* Checks whether the current access control context (call stack) has
* the given permission for the given bundle location and throws a
* SecurityException
if this is not the case.
*
* @param name The bundle location to check for permission. If this
* is null
permission is always granted.
* @param checkOwn If {@code false} permission is always granted if
* {@code name} is the same the using bundle's location.
*
* @throws SecurityException if the access control context does not
* have the appropriate permission
*/
void checkPermission( final ConfigurationManager configurationManager, String name, boolean checkOwn )
{
checkPermission(configurationManager, name, ConfigurationPermission.CONFIGURE, checkOwn);
}
/**
* Checks whether the current access control context (call stack) has
* the given permission for the given bundle location and throws a
* SecurityException
if this is not the case.
*
* @param name The bundle location to check for permission. If this
* is null
permission is always granted.
* @param action The action to check.
* @param checkOwn If {@code false} permission is always granted if
* {@code name} is the same as the using bundle's location.
*
* @throws SecurityException if the access control context does not
* have the appropriate permission
*/
void checkPermission( final ConfigurationManager configurationManager, String name, String action, boolean checkOwn )
{
// the caller's permission must be checked
final SecurityManager sm = System.getSecurityManager();
if ( sm != null )
{
// CM 1.4 / 104.11.1 Implicit permission
if ( name != null && ( checkOwn || !name.equals( Activator.getLocation(getBundle()) ) ) )
{
try
{
sm.checkPermission( new ConfigurationPermission( name, action ) );
Log.logger.log( LogService.LOG_DEBUG,
"Explicit Permission; grant {0} permission on configuration bound to {1} to bundle {2}",
new Object[]
{ action, name, Activator.getLocation(getBundle()) } );
}
catch ( SecurityException se )
{
Log.logger
.log(
LogService.LOG_DEBUG,
"No Permission; denied {0} permission on configuration bound to {1} to bundle {2}; reason: {3}",
new Object[]
{ action, name, Activator.getLocation(getBundle()), se.getMessage() } );
throw se;
}
}
else if ( Log.logger.isLogEnabled( LogService.LOG_DEBUG ) )
{
Log.logger.log( LogService.LOG_DEBUG,
"Implicit Permission; grant {0} permission on configuration bound to {1} to bundle {2}",
new Object[]
{ action, name, Activator.getLocation(getBundle()) } );
}
}
else if ( Log.logger.isLogEnabled( LogService.LOG_DEBUG ) )
{
Log.logger.log( LogService.LOG_DEBUG,
"No SecurityManager installed; grant {0} permission on configuration bound to {1} to bundle {2}",
new Object[]
{ action, name, Activator.getLocation(getBundle()) } );
}
}
/**
* Returns the {@link ConfigurationManager} backing this configuration
* admin instance or throws {@code IllegalStateException} if already
* disposed off.
*
* @return The {@link ConfigurationManager} instance if still active
* @throws IllegalStateException if this instance has been
* {@linkplain #dispose() disposed off} already.
*/
private ConfigurationManager getConfigurationManager()
{
if ( this.configurationManager == null )
{
throw new IllegalStateException( "Configuration Admin service has been unregistered" );
}
return this.configurationManager;
}
/**
* @see org.osgi.service.cm.ConfigurationAdmin#getFactoryConfiguration(java.lang.String, java.lang.String, java.lang.String)
*/
@Override
public Configuration getFactoryConfiguration(String factoryPid, String name, String location) throws IOException
{
final ConfigurationManager configurationManager = getConfigurationManager();
Log.logger.log( LogService.LOG_DEBUG, "getFactoryConfiguration(factoryPid={0}, name={1}, location={2})", new Object[]
{ factoryPid, name, location } );
final String pid = factoryPid + '~' + name;
// CM 1.4 / 104.13.2.3
this.checkPermission( configurationManager, ( location == null ) ? "*" : location, false );
ConfigurationImpl config = configurationManager.getConfiguration( pid );
if ( config == null )
{
config = configurationManager.createFactoryConfiguration( pid, factoryPid, location );
}
else
{
final String configLocation = config.getBundleLocation();
this.checkPermission( configurationManager, ( configLocation == null ) ? "*" : configLocation, false );
}
return this.wrap( config );
}
/**
* @see org.osgi.service.cm.ConfigurationAdmin#getFactoryConfiguration(java.lang.String, java.lang.String)
*/
@Override
public Configuration getFactoryConfiguration(String factoryPid, String name) throws IOException {
final ConfigurationManager configurationManager = getConfigurationManager();
Log.logger.log( LogService.LOG_DEBUG, "getFactoryConfiguration(factoryPid={0}, name={1})", new Object[]
{ factoryPid, name } );
final String pid = factoryPid + '~' + name;
ConfigurationImpl config = configurationManager.getConfiguration( pid );
if ( config == null )
{
config = configurationManager.createFactoryConfiguration( pid, factoryPid, null );
// FELIX-3360: configuration creation with implicit binding is dynamic
config.setDynamicBundleLocation( Activator.getLocation(getBundle()), false );
}
else
{
if ( config.getBundleLocation() == null )
{
Log.logger.log( LogService.LOG_DEBUG, "Binding configuration {0} (isNew: {1}) to bundle {2}",
new Object[]
{ config.getPid(), config.isNew() ? Boolean.TRUE : Boolean.FALSE,
Activator.getLocation(this.getBundle()) } );
// FELIX-3360: first implicit binding is dynamic
config.setDynamicBundleLocation( Activator.getLocation(getBundle()), true );
}
else
{
// CM 1.4 / 104.13.2.3
this.checkPermission( configurationManager, config.getBundleLocation(), false );
}
}
return this.wrap( config );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy