blob: 7f974852a297651453875d7d970b94e3969e83af [file] [log] [blame]
/*
* 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 java.util.Dictionary;
import java.util.EnumSet;
import java.util.Set;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationPermission;
import org.osgi.service.cm.ReadOnlyConfigurationException;
import org.osgi.service.log.LogService;
/**
* The <code>ConfigurationAdapter</code> is just an adapter to the internal
* configuration object. Instances of this class are returned as Configuration
* objects to the client, where each caller gets a fresh instance of this
* class while internal Configuration objects are shared.
*/
public class ConfigurationAdapter implements Configuration
{
private final ConfigurationAdminImpl configurationAdmin;
private final ConfigurationImpl delegatee;
ConfigurationAdapter( ConfigurationAdminImpl configurationAdmin, ConfigurationImpl delegatee )
{
this.configurationAdmin = configurationAdmin;
this.delegatee = delegatee;
}
/**
* @see org.apache.felix.cm.impl.ConfigurationImpl#getPid()
*/
@Override
public String getPid()
{
checkDeleted();
return delegatee.getPidString();
}
/**
* @see org.apache.felix.cm.impl.ConfigurationImpl#getFactoryPid()
*/
@Override
public String getFactoryPid()
{
checkDeleted();
return delegatee.getFactoryPidString();
}
/**
* @see org.apache.felix.cm.impl.ConfigurationImpl#getBundleLocation()
*/
@Override
public String getBundleLocation()
{
// CM 1.4 / 104.13.2.4
final String bundleLocation = delegatee.getBundleLocation();
//delegatee.getConfigurationManager().log( LogService.LOG_DEBUG, "getBundleLocation() ==> {0}", new Object[]
// { bundleLocation } );
checkActive();
configurationAdmin.checkPermission( delegatee.getConfigurationManager(), ( bundleLocation == null ) ? "*" : bundleLocation, true );
checkDeleted();
return bundleLocation;
}
/**
* @param bundleLocation
* @see org.apache.felix.cm.impl.ConfigurationImpl#setStaticBundleLocation(String)
*/
@Override
public void setBundleLocation( String bundleLocation )
{
Log.logger.log( LogService.LOG_DEBUG, "setBundleLocation(bundleLocation={0})",
new Object[]
{ bundleLocation } );
// CM 1.4 / 104.13.2.4
checkActive();
final String configLocation = delegatee.getBundleLocation();
configurationAdmin.checkPermission( delegatee.getConfigurationManager(), ( configLocation == null ) ? "*" : configLocation, true );
configurationAdmin.checkPermission( delegatee.getConfigurationManager(), ( bundleLocation == null ) ? "*" : bundleLocation, true );
checkDeleted();
delegatee.setStaticBundleLocation( bundleLocation );
}
/**
* @throws IOException
* @see org.apache.felix.cm.impl.ConfigurationImpl#update()
*/
@Override
public void update() throws IOException
{
Log.logger.log( LogService.LOG_DEBUG, "update()", ( Throwable ) null );
checkActive();
checkDeleted();
delegatee.update();
}
/**
* @param properties
* @throws IOException
* @see org.apache.felix.cm.impl.ConfigurationImpl#update(java.util.Dictionary)
*/
@Override
public void update( Dictionary<String, ?> properties ) throws IOException
{
Log.logger.log( LogService.LOG_DEBUG, "update(properties={0})", new Object[]
{ properties } );
checkActive();
checkDeleted();
checkLocked();
delegatee.update( properties );
}
@Override
public Dictionary<String, Object> getProperties()
{
//delegatee.getConfigurationManager().log( LogService.LOG_DEBUG, "getProperties()", ( Throwable ) null );
checkDeleted();
// return a deep copy since the spec says, that modification of
// any value should not modify the internal, stored value
return delegatee.getProperties( true );
}
@Override
public long getChangeCount()
{
//delegatee.getConfigurationManager().log( LogService.LOG_DEBUG, "getChangeCount()", ( Throwable ) null );
checkDeleted();
return delegatee.getRevision();
}
/**
* @throws IOException
* @see org.apache.felix.cm.impl.ConfigurationImpl#delete()
*/
@Override
public void delete() throws IOException
{
Log.logger.log( LogService.LOG_DEBUG, "delete()", ( Throwable ) null );
checkActive();
checkDeleted();
delegatee.delete();
}
/**
* @see org.osgi.service.cm.Configuration#updateIfDifferent(java.util.Dictionary)
*/
@SuppressWarnings("unchecked")
@Override
public boolean updateIfDifferent(final Dictionary<String, ?> properties) throws IOException
{
Log.logger.log( LogService.LOG_DEBUG, "updateIfDifferent(properties={0})", new Object[]
{ properties } );
checkActive();
checkDeleted();
checkLocked();
if ( !ConfigurationImpl.equals((Dictionary<String, Object>)properties, delegatee.getProperties(false)) )
{
delegatee.update( properties );
return true;
}
return false;
}
/**
* @see org.osgi.service.cm.Configuration#addAttributes(org.osgi.service.cm.Configuration.ConfigurationAttribute[])
*/
@Override
public void addAttributes(final ConfigurationAttribute... attrs) throws IOException
{
checkDeleted();
final String bundleLocation = delegatee.getBundleLocation();
this.configurationAdmin.checkPermission(this.delegatee.getConfigurationManager(),
( bundleLocation == null ) ? "*" : bundleLocation,
ConfigurationPermission.ATTRIBUTE,
false);
Log.logger.log( LogService.LOG_DEBUG, "addAttributes({0})", attrs );
if ( attrs != null )
{
for(ConfigurationAttribute ca : attrs)
{
// locked is the only attribute at the moment
if ( ca == ConfigurationAttribute.READ_ONLY ) {
delegatee.setLocked( true );
}
}
}
}
/**
* @see org.osgi.service.cm.Configuration#getAttributes()
*/
@Override
public Set<ConfigurationAttribute> getAttributes()
{
checkDeleted();
if ( delegatee.isLocked() )
{
return EnumSet.of(ConfigurationAttribute.READ_ONLY);
}
return EnumSet.noneOf(ConfigurationAttribute.class);
}
/**
* @see org.osgi.service.cm.Configuration#removeAttributes(org.osgi.service.cm.Configuration.ConfigurationAttribute[])
*/
@Override
public void removeAttributes(final ConfigurationAttribute... attrs) throws IOException
{
checkDeleted();
final String bundleLocation = delegatee.getBundleLocation();
this.configurationAdmin.checkPermission(this.delegatee.getConfigurationManager(),
( bundleLocation == null ) ? "*" : bundleLocation,
ConfigurationPermission.ATTRIBUTE,
false);
Log.logger.log( LogService.LOG_DEBUG, "removeAttributes({0})", attrs );
if ( attrs != null )
{
for(ConfigurationAttribute ca : attrs)
{
// locked is the only attribute at the moment
if ( ca == ConfigurationAttribute.READ_ONLY ) {
delegatee.setLocked( false );
}
}
}
}
/**
* @see org.osgi.service.cm.Configuration#getProcessedProperties(ServiceReference)
*/
@Override
public Dictionary<String, Object> getProcessedProperties(ServiceReference<?> sr)
{
final Dictionary<String, Object> props = this.getProperties();
this.delegatee.getConfigurationManager().callPlugins(props, sr,
(String)props.get(Constants.SERVICE_PID),
(String)props.get(ConfigurationAdmin.SERVICE_FACTORYPID));
return props;
}
/**
* @see org.apache.felix.cm.impl.ConfigurationImpl#hashCode()
*/
@Override
public int hashCode()
{
return delegatee.hashCode();
}
/**
* @param obj
* @see org.apache.felix.cm.impl.ConfigurationImpl#equals(java.lang.Object)
*/
@Override
public boolean equals( Object obj )
{
return delegatee.equals( obj );
}
/**
* @see org.apache.felix.cm.impl.ConfigurationImpl#toString()
*/
@Override
public String toString()
{
return delegatee.toString();
}
/**
* Checks whether this configuration object is backed by an active
* Configuration Admin Service (ConfigurationManager here).
*
* @throws IllegalStateException If this configuration object is not
* backed by an active ConfigurationManager
*/
private void checkActive()
{
if ( !delegatee.isActive() )
{
throw new IllegalStateException( "Configuration " + delegatee.getPid()
+ " not backed by an active Configuration Admin Service" );
}
}
/**
* Checks whether this configuration object has already been deleted.
*
* @throws IllegalStateException If this configuration object has been
* deleted.
*/
private void checkDeleted()
{
if ( delegatee.isDeleted() )
{
throw new IllegalStateException( "Configuration " + delegatee.getPid() + " deleted" );
}
}
/**
* Checks whether this configuration object is locked.
*
* @throws ReadOnlyConfigurationException If this configuration object is locked.
*/
private void checkLocked() throws IOException
{
if ( delegatee.isLocked() )
{
throw new ReadOnlyConfigurationException( "Configuration " + delegatee.getPid() + " is read-only" );
}
}
}