FELIX-3481 Start using targeted PIDs:
- generify factory and configuration caches
- try to find targeted [factory] configuration(s)
- Replace string pid and factoryPid fields in ConfigurationImpl and Factory
by TargetedPID typed fields
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1357149 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java
index f1e95bc..263a6e4 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationAdapter.java
@@ -52,7 +52,7 @@
public String getPid()
{
checkDeleted();
- return delegatee.getPid();
+ return delegatee.getPidString();
}
@@ -62,7 +62,7 @@
public String getFactoryPid()
{
checkDeleted();
- return delegatee.getFactoryPid();
+ return delegatee.getFactoryPidString();
}
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java
index 6891060..79e6f0c 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationBase.java
@@ -22,6 +22,7 @@
import java.io.IOException;
import java.util.Dictionary;
import org.apache.felix.cm.PersistenceManager;
+import org.apache.felix.cm.impl.helper.TargetedPID;
import org.osgi.service.log.LogService;
@@ -38,7 +39,7 @@
private final PersistenceManager persistenceManager;
// the basic ID of this instance
- private final String baseId;
+ private final TargetedPID baseId;
protected ConfigurationBase( final ConfigurationManager configurationManager,
final PersistenceManager persistenceManager, final String baseId )
@@ -55,7 +56,7 @@
this.configurationManager = configurationManager;
this.persistenceManager = persistenceManager;
- this.baseId = baseId;
+ this.baseId = new TargetedPID( baseId );
}
@@ -71,7 +72,7 @@
}
- String getBaseId()
+ TargetedPID getBaseId()
{
return baseId;
}
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
index 90aaf25..b721821 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationImpl.java
@@ -24,6 +24,7 @@
import java.util.Hashtable;
import org.apache.felix.cm.PersistenceManager;
+import org.apache.felix.cm.impl.helper.TargetedPID;
import org.osgi.framework.Constants;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
@@ -99,7 +100,7 @@
* The factory PID of this configuration or <code>null</code> if this
* is not a factory configuration.
*/
- private final String factoryPID;
+ private final TargetedPID factoryPID;
/**
* The statically bound bundle location, which is set explicitly by calling
@@ -145,12 +146,13 @@
{
super( configurationManager, persistenceManager, ( String ) properties.remove( Constants.SERVICE_PID ) );
- this.factoryPID = ( String ) properties.remove( ConfigurationAdmin.SERVICE_FACTORYPID );
+ final String factoryPid = ( String ) properties.remove( ConfigurationAdmin.SERVICE_FACTORYPID );
+ this.factoryPID = ( factoryPid == null ) ? null : new TargetedPID( factoryPid );
this.isDeleted = false;
// set bundle location from persistence and/or check for dynamic binding
this.staticBundleLocation = ( String ) properties.remove( ConfigurationAdmin.SERVICE_BUNDLELOCATION ) ;
- this.dynamicBundleLocation = configurationManager.getDynamicBundleLocation( getBaseId() );
+ this.dynamicBundleLocation = configurationManager.getDynamicBundleLocation( getBaseId().toString() );
// set the properties internally
configureFromPersistence( properties );
@@ -162,12 +164,12 @@
{
super( configurationManager, persistenceManager, pid );
- this.factoryPID = factoryPid;
+ this.factoryPID = ( factoryPid == null ) ? null : new TargetedPID( factoryPid );
this.isDeleted = false;
// set bundle location from persistence and/or check for dynamic binding
this.staticBundleLocation = bundleLocation;
- this.dynamicBundleLocation = configurationManager.getDynamicBundleLocation( getBaseId() );
+ this.dynamicBundleLocation = configurationManager.getDynamicBundleLocation( getBaseId().toString() );
// first "update"
this.properties = null;
@@ -186,24 +188,34 @@
public void delete() throws IOException
{
this.isDeleted = true;
- getPersistenceManager().delete( this.getPid() );
- getConfigurationManager().setDynamicBundleLocation( this.getPid(), null );
+ getPersistenceManager().delete( this.getPidString() );
+ getConfigurationManager().setDynamicBundleLocation( this.getPidString(), null );
getConfigurationManager().deleted( this );
}
- public String getPid()
+ public String getPidString()
+ {
+ return getBaseId().toString();
+ }
+
+
+ public TargetedPID getPid()
{
return getBaseId();
}
- public String getFactoryPid()
+ public String getFactoryPidString()
{
- return factoryPID;
+ return (factoryPID == null) ? null : factoryPID.toString();
}
+ public TargetedPID getFactoryPid()
+ {
+ return factoryPID;
+ }
/**
@@ -266,7 +278,7 @@
final String oldBundleLocation = getBundleLocation();
this.dynamicBundleLocation = bundleLocation;
- this.getConfigurationManager().setDynamicBundleLocation( this.getBaseId(), bundleLocation );
+ this.getConfigurationManager().setDynamicBundleLocation( this.getPidString(), bundleLocation );
// CM 1.4
if ( dispatchConfiguration )
@@ -288,7 +300,7 @@
if ( this.getBundleLocation() == null )
{
getConfigurationManager().log( LogService.LOG_DEBUG, "Dynamically binding config {0} to {1}", new Object[]
- { getPid(), bundleLocation } );
+ { getPidString(), bundleLocation } );
setDynamicBundleLocation( bundleLocation, true );
}
@@ -335,15 +347,15 @@
if ( localPersistenceManager != null )
{
// read configuration from persistence (again)
- if ( localPersistenceManager.exists( getPid() ) )
+ if ( localPersistenceManager.exists( getPidString() ) )
{
- Dictionary properties = localPersistenceManager.load( getPid() );
+ Dictionary properties = localPersistenceManager.load( getPidString() );
// ensure serviceReference pid
String servicePid = ( String ) properties.get( Constants.SERVICE_PID );
- if ( servicePid != null && !getPid().equals( servicePid ) )
+ if ( servicePid != null && !getPidString().equals( servicePid ) )
{
- throw new IOException( "PID of configuration file does match requested PID; expected " + getPid()
+ throw new IOException( "PID of configuration file does match requested PID; expected " + getPidString()
+ ", got " + servicePid );
}
@@ -367,34 +379,15 @@
CaseInsensitiveDictionary newProperties = new CaseInsensitiveDictionary( properties );
getConfigurationManager().log( LogService.LOG_DEBUG, "Updating config {0} with {1}", new Object[]
- { getPid(), newProperties } );
+ { getPidString(), newProperties } );
setAutoProperties( newProperties, true );
// persist new configuration
- localPersistenceManager.store( getPid(), newProperties );
+ localPersistenceManager.store( getPidString(), newProperties );
// if this is a factory configuration, update the factory with
- String factoryPid = getFactoryPid();
- if ( factoryPid != null )
- {
- Factory factory = getConfigurationManager().getFactory( factoryPid );
- if ( factory.addPID( getPid() ) )
- {
- // only write back if the pid was not already registered
- // with the factory
- try
- {
- factory.store();
- }
- catch ( IOException ioe )
- {
- getConfigurationManager().log( LogService.LOG_ERROR,
- "Failure storing factory {0} with new configuration {1}", new Object[]
- { factoryPid, getPid(), ioe } );
- }
- }
- }
+ updateFactory();
// finally assign the configuration for use
configure( newProperties );
@@ -416,7 +409,7 @@
if ( obj instanceof Configuration )
{
- return getPid().equals( ( ( Configuration ) obj ).getPid() );
+ return getPidString().equals( ( ( Configuration ) obj ).getPid() );
}
return false;
@@ -425,13 +418,13 @@
public int hashCode()
{
- return getPid().hashCode();
+ return getPidString().hashCode();
}
public String toString()
{
- return "Configuration PID=" + getPid() + ", factoryPID=" + factoryPID + ", bundleLocation=" + getBundleLocation();
+ return "Configuration PID=" + getPidString() + ", factoryPID=" + factoryPID + ", bundleLocation=" + getBundleLocation();
}
@@ -451,19 +444,56 @@
*/
void ensureFactoryConfigPersisted() throws IOException
{
- if ( this.factoryPID != null && isNew() && !getPersistenceManager().exists( getPid() ) )
+ if ( this.factoryPID != null && isNew() && !getPersistenceManager().exists( getPidString() ) )
{
storeNewConfiguration();
}
}
+ /**
+ * Persists a new (freshly created) configuration with a marker for
+ * it to be a new configuration.
+ *
+ * @throws IOException If an error occurrs storing the configuraiton
+ */
private void storeNewConfiguration() throws IOException
{
Dictionary props = new Hashtable();
setAutoProperties( props, true );
props.put( CONFIGURATION_NEW, Boolean.TRUE );
- getPersistenceManager().store( getPid(), props );
+ getPersistenceManager().store( getPidString(), props );
+ }
+
+
+ /**
+ * Makes sure the configuration is added to the {@link Factory} (and
+ * the factory be stored if updated) if this is a factory
+ * configuration.
+ *
+ * @throws IOException If an error occurrs storing the {@link Factory}
+ */
+ private void updateFactory() throws IOException {
+ String factoryPid = getFactoryPidString();
+ if ( factoryPid != null )
+ {
+ Factory factory = getConfigurationManager().getOrCreateFactory( factoryPid );
+ if ( factory.addPID( getPidString() ) )
+ {
+ // only write back if the pid was not already registered
+ // with the factory
+ try
+ {
+ factory.store();
+ }
+ catch ( IOException ioe )
+ {
+ getConfigurationManager().log( LogService.LOG_ERROR,
+ "Failure storing factory {0} with new configuration {1}", new Object[]
+ { factoryPid, getPidString(), ioe } );
+ }
+ }
+ }
}
@@ -489,7 +519,7 @@
}
// only store now, if this is not a new configuration
- getPersistenceManager().store( getPid(), props );
+ getPersistenceManager().store( getPidString(), props );
}
@@ -576,8 +606,8 @@
void setAutoProperties( Dictionary properties, boolean withBundleLocation )
{
// set pid and factory pid in the properties
- replaceProperty( properties, Constants.SERVICE_PID, getPid() );
- replaceProperty( properties, ConfigurationAdmin.SERVICE_FACTORYPID, factoryPID );
+ replaceProperty( properties, Constants.SERVICE_PID, getPidString() );
+ replaceProperty( properties, ConfigurationAdmin.SERVICE_FACTORYPID, getFactoryPidString() );
// bundle location is not set here
if ( withBundleLocation )
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
index b36b014..fd5ca09 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
@@ -29,6 +29,7 @@
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
@@ -163,11 +164,11 @@
private int pmtCount;
// the cache of Factory instances mapped by their factory PID
- private final Map factories = new HashMap();
+ private final HashMap<String, Factory> factories = new HashMap<String, Factory>();
// the cache of Configuration instances mapped by their PID
// have this always set to prevent NPE on bundle shutdown
- private final Map configurations = new HashMap();
+ private final HashMap<String, ConfigurationImpl> configurations = new HashMap<String, ConfigurationImpl>();
/**
* The map of dynamic configuration bindings. This maps the
@@ -273,14 +274,14 @@
props.put( Constants.SERVICE_VENDOR, "Apache Software Foundation" );
configurationAdminRegistration = bundleContext.registerService( ConfigurationAdmin.class.getName(), caf, props );
+ // start handling ManagedService[Factory] services
+ managedServiceTracker = new ManagedServiceTracker(this);
+ managedServiceFactoryTracker = new ManagedServiceFactoryTracker(this);
+
// start processing the event queues only after registering the service
// see FELIX-2813 for details
this.updateThread.start();
this.eventThread.start();
-
- // start handling ManagedService[Factory] services
- managedServiceTracker = new ManagedServiceTracker(this);
- managedServiceFactoryTracker = new ManagedServiceFactoryTracker(this);
}
@@ -290,6 +291,10 @@
// stop handling bundle events immediately
handleBundleEvents = false;
+ // stop handling ManagedService[Factory] services
+ managedServiceFactoryTracker.close();
+ managedServiceTracker.close();
+
// stop queue processing before unregistering the service
// see FELIX-2813 for details
if ( updateThread != null )
@@ -315,10 +320,6 @@
// unregistration the manager is still alive and can react
isActive = false;
- // stop handling ManagedService[Factory] services
- managedServiceFactoryTracker.close();
- managedServiceTracker.close();
-
// don't care for PersistenceManagers any more
persistenceManagerTracker.close();
@@ -370,7 +371,7 @@
{
synchronized ( configurations )
{
- return ( ConfigurationImpl ) configurations.get( pid );
+ return configurations.get( pid );
}
}
@@ -379,7 +380,7 @@
{
synchronized ( configurations )
{
- return ( ConfigurationImpl[] ) configurations.values().toArray(
+ return configurations.values().toArray(
new ConfigurationImpl[configurations.size()] );
}
}
@@ -389,13 +390,14 @@
{
synchronized ( configurations )
{
- Object existing = configurations.get( configuration.getPid() );
+ final String pid = configuration.getPidString();
+ final Object existing = configurations.get( pid );
if ( existing != null )
{
return ( ConfigurationImpl ) existing;
}
- configurations.put( configuration.getPid(), configuration );
+ configurations.put( pid, configuration );
return configuration;
}
}
@@ -405,7 +407,7 @@
{
synchronized ( configurations )
{
- configurations.remove( configuration.getPid() );
+ configurations.remove( configuration.getPidString() );
}
}
@@ -414,7 +416,7 @@
{
synchronized ( factories )
{
- return ( Factory ) factories.get( factoryPid );
+ return factories.get( factoryPid );
}
}
@@ -423,7 +425,7 @@
{
synchronized ( factories )
{
- return ( Factory[] ) factories.values().toArray( new Factory[factories.size()] );
+ return factories.values().toArray( new Factory[factories.size()] );
}
}
@@ -432,7 +434,7 @@
{
synchronized ( factories )
{
- factories.put( factory.getFactoryPid(), factory );
+ factories.put( factory.getFactoryPidString(), factory );
}
}
@@ -472,6 +474,49 @@
return cacheConfiguration( createConfiguration( createPid( factoryPid ), factoryPid, location ) );
}
+ /**
+ * Returns a targeted configuration for the given service PID and
+ * the reference target service.
+ *
+ * @param rawPid The raw service PID to get targeted configuration for.
+ * @param target The target <code>ServiceReference</code> to get
+ * configuration for.
+ * @return The best matching targeted configuration or <code>null</code>
+ * if there is no configuration at all.
+ * @throwss IOException if an error occurrs reading configurations
+ * from persistence.
+ */
+ ConfigurationImpl getTargetedConfiguration( final String rawPid, final ServiceReference target ) throws IOException
+ {
+ final Bundle serviceBundle = target.getBundle();
+ if ( serviceBundle != null )
+ {
+ // for pre-1.5 API compatibility
+ final StringBuffer targetedPid = new StringBuffer( rawPid );
+ int i = 3;
+ String[] names = new String[4];
+ names[i--] = targetedPid.toString();
+ targetedPid.append( '|' ).append( serviceBundle.getSymbolicName() );
+ names[i--] = targetedPid.toString();
+ targetedPid.append( '|' ).append( TargetedPID.getBundleVersion( serviceBundle ) );
+ names[i--] = targetedPid.toString();
+ targetedPid.append( '|' ).append( serviceBundle.getLocation() );
+ names[i--] = targetedPid.toString();
+
+ for ( String candidate : names )
+ {
+ ConfigurationImpl config = getConfiguration( candidate );
+ if ( config != null )
+ {
+ return config;
+ }
+ }
+ }
+
+ // service already unregistered, nothing to do really
+ return null;
+ }
+
/**
* Returns the {@link ConfigurationImpl} with the given PID if
@@ -626,7 +671,7 @@
{
// remove the configuration from the cache
removeConfiguration( config );
- fireConfigurationEvent( ConfigurationEvent.CM_DELETED, config.getPid(), config.getFactoryPid() );
+ fireConfigurationEvent( ConfigurationEvent.CM_DELETED, config.getPidString(), config.getFactoryPidString() );
updateThread.schedule( new DeleteConfiguration( config ) );
log( LogService.LOG_DEBUG, "DeleteConfiguration({0}) scheduled", new Object[]
{ config.getPid() } );
@@ -637,7 +682,7 @@
{
if ( fireEvent )
{
- fireConfigurationEvent( ConfigurationEvent.CM_UPDATED, config.getPid(), config.getFactoryPid() );
+ fireConfigurationEvent( ConfigurationEvent.CM_UPDATED, config.getPidString(), config.getFactoryPidString() );
}
updateThread.schedule( new UpdateConfiguration( config ) );
log( LogService.LOG_DEBUG, "UpdateConfiguration({0}) scheduled", new Object[]
@@ -647,7 +692,7 @@
void locationChanged( ConfigurationImpl config, String oldLocation )
{
- fireConfigurationEvent( ConfigurationEvent.CM_LOCATION_CHANGED, config.getPid(), config.getFactoryPid() );
+ fireConfigurationEvent( ConfigurationEvent.CM_LOCATION_CHANGED, config.getPidString(), config.getFactoryPidString() );
if ( oldLocation != null && !config.isNew() )
{
updateThread.schedule( new LocationChanged( config, oldLocation ) );
@@ -854,14 +899,100 @@
}
+ /**
+ * Returns a list of {@link Factory} instances according to the
+ * Configuration Admin 1.5 specification for targeted PIDs (Section
+ * 104.3.2)
+ *
+ * @param rawFactoryPid The raw factory PID without any targetting.
+ * @param target The <code>ServiceReference</code> of the service to
+ * be supplied with targeted configuration.
+ * @return A list of {@link Factory} instances as listed above. This
+ * list will always at least include an instance for the
+ * <code>rawFactoryPid</code>. Other instances are only included
+ * if existing.
+ * @throws IOException If an error occurrs reading any of the
+ * {@link Factory} instances from persistence
+ */
+ List<Factory> getTargetedFactories( final String rawFactoryPid, final ServiceReference target ) throws IOException
+ {
+ LinkedList<Factory> factories = new LinkedList<Factory>();
+
+ final Bundle serviceBundle = target.getBundle();
+ if ( serviceBundle != null )
+ {
+ // for pre-1.5 API compatibility
+ final StringBuffer targetedPid = new StringBuffer( rawFactoryPid );
+ factories.add( getOrCreateFactory( targetedPid.toString() ) );
+
+ targetedPid.append( '|' ).append( serviceBundle.getSymbolicName() );
+ Factory f = getFactory( targetedPid.toString() );
+ if ( f != null )
+ {
+ factories.add( 0, f );
+ }
+
+ targetedPid.append( '|' ).append( TargetedPID.getBundleVersion( serviceBundle ) );
+ f = getFactory( targetedPid.toString() );
+ if ( f != null )
+ {
+ factories.add( 0, f );
+ }
+
+ targetedPid.append( '|' ).append( serviceBundle.getLocation() );
+ f = getFactory( targetedPid.toString() );
+ if ( f != null )
+ {
+ factories.add( 0, f );
+ }
+ }
+
+ return factories;
+ }
+
+
+ /**
+ * Gets the factory with the exact identifier from the cached or from
+ * the persistence managers. If no factory exists already one is
+ * created and cached.
+ *
+ * @param factoryPid The PID of the {@link Factory} to return
+ * @return The existing or newly created {@link Factory}
+ * @throws IOException If an error occurrs reading the factory from
+ * a {@link PersistenceManager}
+ */
+ Factory getOrCreateFactory( String factoryPid ) throws IOException
+ {
+ Factory factory = getFactory( factoryPid );
+ if ( factory != null )
+ {
+ return factory;
+ }
+
+ return createFactory( factoryPid );
+ }
+
+
+ /**
+ * Gets the factory with the exact identifier from the cached or from
+ * the persistence managers. If no factory exists <code>null</code>
+ * is returned.
+ *
+ * @param factoryPid The PID of the {@link Factory} to return
+ * @return The existing {@link Factory} or <code>null</code>
+ * @throws IOException If an error occurrs reading the factory from
+ * a {@link PersistenceManager}
+ */
Factory getFactory( String factoryPid ) throws IOException
{
+ // check for cached factory
Factory factory = getCachedFactory( factoryPid );
if ( factory != null )
{
return factory;
}
+ // try to load factory from persistence
PersistenceManager[] pmList = getPersistenceManagers();
for ( int i = 0; i < pmList.length; i++ )
{
@@ -873,11 +1004,14 @@
}
}
- // if getting here, there is no configuration yet, optionally create new
- return createFactory( factoryPid );
+ // no existing factory
+ return null;
}
+ /**
+ * Creates a new factory with the given <code>factoryPid</code>.
+ */
Factory createFactory( String factoryPid )
{
Factory factory = new Factory( this, getPersistenceManagers()[0], factoryPid );
@@ -1195,7 +1329,7 @@
long revision = -1;
try
{
- config = getConfiguration( pid );
+ config = getTargetedConfiguration( pid, sr );
if ( config != null )
{
synchronized ( config )
@@ -1224,8 +1358,8 @@
// check configuration and call plugins if existing
if ( config != null )
{
- log( LogService.LOG_DEBUG, "Updating configuration {0} to revision #{1}", new Object[]
- { pid, new Long( revision ) } );
+ log( LogService.LOG_DEBUG, "Updating service {0} to with configuration {1}@{2}", new Object[]
+ { pid, this.config.getPid(), new Long( revision ) } );
Bundle serviceBundle = sr.getBundle();
if ( serviceBundle == null )
@@ -1296,13 +1430,13 @@
this.factoryPid = factoryPid;
this.sr = sr;
- Factory factory = null;
+ List<Factory> factories = null;
Map configs = null;
Map revisions = null;
try
{
- factory = getFactory( factoryPid );
- if (factory != null) {
+ factories = getTargetedFactories( factoryPid, sr );
+ for (Factory factory : factories) {
configs = new HashMap();
revisions = new HashMap();
for ( Iterator pi = factory.getPIDs().iterator(); pi.hasNext(); )
@@ -1342,6 +1476,12 @@
{ pid } );
continue;
}
+ /*
+ * this code would catch targeted factory PIDs;
+ * since this is not expected any way, we can
+ * leave this out
+ */
+ /*
else if ( !factoryPid.equals( cfg.getFactoryPid() ) )
{
log( LogService.LOG_ERROR,
@@ -1352,6 +1492,7 @@
factory.storeSilently();
continue;
}
+ */
// get the configuration properties for later
synchronized ( cfg )
@@ -1401,8 +1542,8 @@
final Dictionary properties = ( Dictionary ) entry.getValue();
final long revision = ( ( Long ) revisions.get( cfg ) ).longValue();
- log( LogService.LOG_DEBUG, "Updating configuration {0} to revision #{1}", new Object[]
- { cfg.getPid(), new Long( revision ) } );
+ log( LogService.LOG_DEBUG, "Updating service {0} with configuration {1}/{2}@{3}", new Object[]
+ { this.factoryPid, cfg.getFactoryPid(), cfg.getPid(), new Long( revision ) } );
// CM 1.4 / 104.13.2.1
if ( !canReceive( serviceBundle, cfg.getBundleLocation() ) )
@@ -1435,31 +1576,37 @@
}
}
- private abstract class ConfigurationProvider<T> implements Runnable {
+ private abstract class ConfigurationProvider<T> implements Runnable
+ {
protected final ConfigurationImpl config;
protected final long revision;
protected final Dictionary<String, ?> properties;
protected final BaseTracker<T> helper;
- protected ConfigurationProvider(final ConfigurationImpl config) {
- this.config = config;
- this.helper = ( BaseTracker<T> ) ( ( config.getFactoryPid() == null ) ? managedServiceTracker : managedServiceFactoryTracker );
+
+ protected ConfigurationProvider( final ConfigurationImpl config )
+ {
synchronized ( config )
{
+ this.config = config;
this.revision = config.getRevision();
this.properties = config.getProperties( true );
}
+ this.helper = ( BaseTracker<T> ) ( ( config.getFactoryPid() == null ) ? managedServiceTracker
+ : managedServiceFactoryTracker );
}
- protected TargetedPID getTargetedServicePid() {
- final String factoryPid = this.config.getFactoryPid();
- if (factoryPid == null) {
- return new TargetedPID( this.config.getPid() );
+
+ protected TargetedPID getTargetedServicePid()
+ {
+ final TargetedPID factoryPid = this.config.getFactoryPid();
+ if ( factoryPid != null )
+ {
+ return factoryPid;
}
- return new TargetedPID( factoryPid );
+ return this.config.getPid();
}
-
}
/**
@@ -1558,9 +1705,6 @@
public void run()
{
- final String pid = config.getPid();
- final String factoryPid = config.getFactoryPid();
-
List<ServiceReference<?>> srList = this.helper.getServices( getTargetedServicePid() );
if ( !srList.isEmpty() )
{
@@ -1589,12 +1733,14 @@
}
}
+ final TargetedPID factoryPid = config.getFactoryPid();
if ( factoryPid != null )
{
// remove the pid from the factory
+ final String pid = config.getPidString();
try
{
- Factory factory = getFactory( factoryPid );
+ Factory factory = getOrCreateFactory( factoryPid.toString() );
factory.removePID( pid );
factory.store();
}
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java b/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
index 5122816..b3564ac 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
@@ -26,6 +26,7 @@
import java.util.Set;
import org.apache.felix.cm.PersistenceManager;
+import org.apache.felix.cm.impl.helper.TargetedPID;
/**
@@ -86,12 +87,18 @@
}
- String getFactoryPid()
+ TargetedPID getFactoryPid()
{
return getBaseId();
}
+ String getFactoryPidString()
+ {
+ return getFactoryPid().toString();
+ }
+
+
Set getPIDs()
{
return new HashSet( pids );
@@ -119,7 +126,7 @@
props.put( FACTORY_PID_LIST, pids.toArray( new String[pids.size()] ) );
}
- String id = factoryPidToIdentifier( this.getFactoryPid() );
+ String id = factoryPidToIdentifier( this.getFactoryPid().toString() );
if ( props.isEmpty() )
{
getPersistenceManager().delete( id );
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java
index 58eed84..6910eaf 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceFactoryTracker.java
@@ -42,8 +42,8 @@
{
try
{
- Dictionary props = getProperties( rawProps, config.getFactoryPid(), reference );
- service.updated( config.getPid(), props );
+ Dictionary props = getProperties( rawProps, config.getFactoryPidString(), reference );
+ service.updated( config.getPidString(), props );
}
catch ( Throwable t )
{
@@ -65,7 +65,7 @@
{
try
{
- service.deleted( config.getPid() );
+ service.deleted( config.getPidString() );
}
catch ( Throwable t )
{
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java
index 56f81a2..b5e1f29 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/ManagedServiceTracker.java
@@ -61,7 +61,7 @@
{
if ( properties != null )
{
- properties = getProperties( properties, config.getPid(), service );
+ properties = getProperties( properties, config.getPidString(), service );
}
srv.updated( properties );
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/TargetedPID.java b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/TargetedPID.java
index 784ef8f..d41f045 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/helper/TargetedPID.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/helper/TargetedPID.java
@@ -45,6 +45,26 @@
private final String location;
+ /**
+ * Returns the bundle's version as required for targeted PIDs: If the
+ * bundle has a version the string representation of the version
+ * string converted to a Version object is returned. Otherwise the
+ * string representation of <code>Version.emptyVersion</code> is
+ * returned.
+ * <p>
+ * To remain compatible with pre-R4.2 (Framework API < 1.5) we cannot
+ * use the <code>Bundle.getVersion()</code> method.
+ *
+ * @param bundle The bundle whose version is to be returned.
+ */
+ public static String getBundleVersion( final Bundle bundle )
+ {
+ Object vHeader = bundle.getHeaders().get( Constants.BUNDLE_VERSION );
+ Version version = ( vHeader == null ) ? Version.emptyVersion : new Version( vHeader.toString() );
+ return version.toString();
+ }
+
+
public TargetedPID( final String rawPid )
{
this.rawPid = rawPid;
@@ -137,9 +157,8 @@
}
// bundle version does not match
- Object v = serviceBundle.getHeaders().get( Constants.BUNDLE_VERSION );
- Version s = ( v == null ) ? Version.emptyVersion : new Version( v.toString() );
- if ( !this.version.equals( s.toString() ) )
+
+ if ( !this.version.equals( getBundleVersion( serviceBundle ) ) )
{
return false;
}
@@ -282,4 +301,10 @@
// not the same class or different raw PID
return false;
}
+
+ @Override
+ public String toString()
+ {
+ return this.rawPid;
+ }
}